Webhooks

Learn how to listen to events whenever certain actions occur on your integration.

What are Webhooks?

We trigger events that your application can listen to whenever certain actions occur on your Okra integration. Here's where webhooks come in handy. We deliver payloads for such events to a webhook URL on your server. If you use webhooks, for example, we'll send a balance.success event to your server as soon as a balance is retrieved. The following is a list of events we can send to your webhook URL.

📘

Helpful Tip

We advise using a webhook instead of a callback to deliver value to your clients. Callbacks can fail if a customer's device's network connection fails or is weak, or if the device turns off after a request, among other things that are beyond our and your control.

You can specify your webhook URL on your dashboard where we would send POST requests whenever an event occurs.

Here are some things to note when setting up a webhook URL:

  1. If using .htaccess, remember to add the trailing / to the URL you set.
  2. Do a test post to your URL and ensure the script gets the post body.
  3. Ensure your webhook URL is publicly available (localhost URLs cannot receive events)

Setup Webhook

To set up a new webhook:

  1. From the Environment Switcher in your Okra dashboard, select the environment you want to create a new webhook in.
  2. Select the Settings tab and click API Keys.
  3. Enter the required information in the webhook form.
  • URL: the URL to receive the webhook notifications.
  • Token: an optional bearer token to use if your URL is protected.
    Click Save Changes.
    ✳️ Done! The webhook is now set up and your application will be notified of new events related to any product opted for.

Receiving an event

All you have to do to receive the event is to create an unauthenticated POST route on your application. The event object is sent as JSON in the request body.

// Using Express
app.post("/your/webhook/url", function(req, res) {
    // Retrieve the request's body
    const event = req.body;
    // Do something with event
    res.send(200);
});
<?php
// Retrieve the request's body and parse it as JSON
$input = @file_get_contents("php://input");
$event = json_decode($input);
// Do something with $event
http_response_code(200); // PHP 5.4 or greater
?>

Responding to an event

A 200 OK should be used to respond to an event. This is considered an acknowledgment by your application. If your application returns a status other than 2xx, we will consider it unacknowledged and will continue to send it every hour for the next 72 hours. You don't need to provide a request body or any other parameters because they will be ignored - we only care about the status code.

Okra may timeout waiting for a response if your application is likely to start a long-running task in response to the event, in which case the event will be considered unacknowledged and queued to be raised later. You can avoid duplication by having your application respond with a 200 right away before continuing with the rest of the task.

Example Incoming Webhook

If you're using callbacks with any product, you'll receive a callback when Okra finishes processing the product's data for the Record. Once you receive this callback, you can make an API call to retrieve the product's data.

Below you will see an example of an incoming webhook from Okra's servers. The below example is for AUTH but you will receive webhooks for all products.

Webhook Response

If you've set up webhook notifications for your account, we will also send you a response in the format below:

{
  method: 'IDENTITY',
  callback_type: 'IDENTITY',
  callback_code: 'PRODUCT_IS_READY',
  type: 'CALLBACK',
  code: 'PRODUCT_IS_READY',
  callbackURL: 'https://e2c550b71c3f.ngrok.io/v2/data/login/',
  env: 'production-sandbox',
  status: 'is_success',
  started_at: '2021-04-23T07:39:10.133Z',
  ended_at: '2021-04-23T07:39:35.376Z',
  message: 'Record callback started!',
  options: { },
  bankName: 'Access Bank',
  bankType: 'ind',
  bankId: '5d6fe57a4099cc4b210bbec0',
  bankSlug: 'access-bank',
  record: '6082799e5ad7d31243eb6d43',
  login_type: 'bank',
  customerId: '602d7a668299304ef0df55v2',
  extras: {},
  owner: '5d9288ea182d3d000cb7c481'
}
{
  "method": "AUTH",
  "callback_type": "AUTH",
  "callback_code": "AUTH_SUCCESS",
  "type": "CALLBACK",
  "code": "AUTH_SUCCESS",
  "callbackURL": "",
  "env": "production-sandbox",
  "status": "is_success",
  "started_at": "2021-01-15T13:14:38.359Z",
  "ended_at": "2021-01-15T13:14:38.359Z",
  "message": "Record callback completed!",
  "bankName": "Guaranty Trust Bank",
  "bankType": "ind",
  "bankId": "",
  "bankSlug": "guaranty-trust-bank",
  "record": "",
  "callback_url": "",
  "login_type": "mobile",
  "customerId": ""
}
{
  "method": "IDENTITY",
  "callback_type": "IDENTITY",
  "callback_code": "PRODUCT_IS_READY",
  "type": "CALLBACK",
  "code": "PRODUCT_IS_READY",
  "callbackURL": "https://webhook",
  "env": "production",
  "status": "is_success",
  "started_at": "2021-02-15T06:43:50.554Z",
  "ended_at": "2021-02-15T06:43:50.554Z",
  "message": "Record callback started!",
  "bankName": "Kuda Bank",
  "bankType": "ind",
  "bankId": "5f0cf73e8a8bcc18b8156ad7",
  "bankSlug": "kuda-bank",
  "record": "602a1807b9fdfa599cd3a0b5",
  "login_type": "bank",
  "customerId": "5f636ad0894dbb43795c4e8e",
  "options": {},
  "identity": {
    "id": "5f636ad074b8fde585241eb6",
    "bvn": "22166993390",
    "firstname": "Gaven",
    "middlename": "Big Man"
    "lastname": "Belson",
    "email": [
      "[email protected]"
    ],
    "name": "GAVEN BELSON",
    "fullname": "GAVEN BELSON",
    "dob": "1974-03-01T00:00:00",
    "gender": "male",
    "marital_status": "single",
    "phone": [
      "+19198739291",
      "+18473893931"
    ],
    "address": [
      "9, Huli Blvd."
    ],
    "aliases": [
      "Gav"
    ],
    "details": "https://api.okra.ng/v2/callback?record=602a1807b9fdfa599cd3a0b3&method=IDENTITY",
    "customer": "5f636ad0894dbb43795c4e83",
    "bank": "5f0cf73e8a8bcc18b8156ad7",
    "env": "production"
  }
}
{
  "method": "ACCOUNTS",
  "callback_type": "ACCOUNTS",
  "callback_code": "ACCOUNTS_SUCCESS",
  "type": "CALLBACK",
  "code": "ACCOUNTS_SUCCESS",
  "callbackURL": "",
  "env": "production-sandbox",
  "status": "is_success",
  "started_at": "2021-01-15T13:14:38.359Z",
  "ended_at": "2021-01-15T13:14:38.359Z",
  "message": "Record callback completed!",
  "bankName": "Guaranty Trust Bank",
  "bankType": "ind",
  "bankId": "",
  "accountId": "",
  "nuban": "",
  "bankSlug": "guaranty-trust-bank",
  "record": "",
  "callback_url": "",
  "login_type": "mobile",
  "customerId": ""
}
{
  "method": "BALANCE" or "PERIODIC_BALANCE",
  "callback_type": "BALANCE",
  "callback_code": "BALANCE_SUCCESS",
  "type": "CALLBACK",
  "code": "BALANCE_SUCCESS",
  "callbackURL": "",
  "env": "production",
  "status": "is_success",
  "started_at": "2021-02-15T06:43:51.219Z",
  "ended_at": "2021-02-15T06:43:51.219Z",
  "message": "Record callback started!",
  "bankName": "",
  "bankType": "ind",
  "bankId": "",
  "bankSlug": "",
  "record": "",
  "callback_url": "",
  "nuban": "",
  "login_type": "bank",
  "customerId": ""
}
{
  "method": "TRANSACTIONS",
  "callback_type": "TRANSACTIONS",
  "callback_code": "PRODUCT_IS_READY",
  "type": "CALLBACK",
  "code": "PRODUCT_IS_READY",
  "callbackURL": "",
  "env": "production",
  "status": "is_success",
  "started_at": "2021-02-15T06:44:50.472Z",
  "ended_at": "2021-02-15T06:44:50.472Z",
  "message": "Record callback started!",
  "bankName": "",
  "bankType": "ind",
  "bankId": "",
  "bankSlug": "",
  "record": "",
  "callback_url": "",
  "nuban": "",
  "login_type": "bank",
  "customerId": "",
  "options": {}
}
{
  "method": "INCOME",
  "callback_type": "INCOME",
  "callback_code": "INCOME_FAILED",
  "type": "CALLBACK",
  "code": "INCOME_FAILED",
  "callbackURL": "",
  "env": "production",
  "status": "is_failed",
  "started_at": "2021-02-15T06:44:50.770Z",
  "ended_at": "2021-02-15T06:44:50.770Z",
  "message": "Record callback started!",
  "bankName": "",
  "bankType": "ind",
  "bankId": "",
  "bankSlug": "",
  "record": "",
  "callback_url": "",
  "login_type": "bank",
  "customerId": ""
}
{
  "method": "PAYMENT",
  "callback_type": "PAYMENT_RECURRING" or "PAYMENT" or "PAYMENT_AUTHORIZATION",
  "schedule": {
    "interval": "monthly",
    "startDate": "2021-02-01",
    "endDate": null,
    "history": [
      ...array of payment ID's...
    ],
    "current_amount": 1000
  },
  "callback_code": "PAYMENT_FAILED",
  "type": "CALLBACK",
  "code": "PAYMENT_FAILED",
  "callbackURL": "",
  "env": "production-sandbox",
  "status": "is_failed",
  "started_at": "2021-02-17T14:18:37.608Z",
  "ended_at": "2021-02-17T14:18:40.083Z",
  "message": "Record callback started!",
  "bankName": "Guaranty Trust Bank",
  "accountId": "xxxxx-xxxxxx-xxxxxx",
  "bankType": "ind",
  "bankId": "",
  "bankSlug": "guaranty-trust-bank",
  "record": "",
  "callback_url": ""
}

Checking a Webhook status

curl -X GET https://api.okra.ng/v2/callback?record={RECORD}&method=METHOD
-H 'Content-Type: application/json' 
-H 'Authorization: Bearer <secretKey>'

Product Callbacks/Webhooks

The following are the current events that we have for you. As we hook into more actions in the future, we'll add to this list.

Product

Methods

Endpoint

auth

AUTH

GET /v2/callback?record={RECORD ID HERE}&method=AUTH

identity

IDENTITY

GET /v2/callback?record={RECORD ID HERE}&method=IDENTITY

balance

BALANCE
PERIODIC_BALANCE

GET /v2/callback?record={RECORD ID HERE}&method=BALANCE

income

INCOME

GET /v2/callback?record={RECORD ID HERE}&method=INCOME

transactions

TRANSACTIONS
PERIODIC_TRANSACTIONS

GET /v2/callback?record={RECORD ID HERE}&method=TRANSACTIONS

payment

PAYMENT
PAYMENT_RECURRING

GET /v2/callback?record={RECORD ID HERE}&method=PAYMENT

Other Webhooks

{
"message": <message about the connection/>,
"event": 'USER_DISCONNECT',
"data": {
    "accounts": <id-of-accounts-disconnected/>
    "customer": <id-of-user/>
    "disconnected_at": <time-of-disconnection/>
  }
}
{
"message": <message about the connection/>,
"event": 'USER_REAUTH',
"data": {
    "customer": <id-of-user/>
    "deauthorized_at": <time-of-disconnection/>
  }
}

WebHook Trigger

Overview

The webhook trigger can come in very handy if you need to get the webhooks associated with a particular record id(s), in scenarios where the server goes down unexpectedly or you want to send webhooks to a different server.

You can use the webhook trigger to check the status of a webhook by supplying their record id(s) as the payload to the webhook trigger endpoint.

The way these works is by, calling this endpoint https://api.okra.ng/v2/callback/trigger, and passing the record id or an array of record id(s), or maybe a valid URL you'd like to redirect the webhooks to.

payload = {
     records: ["60b7be20ca7ce542d906e029", "60b7bc9aca7ce542d906e026"] //array of recordIds
     url: "https://yourcompany/webhooks/okra"//callback_url (optional), it default to your saved callback_url
}
{
"status": "success",
"messgae": "webhook trigger successfully initiated",
"data": {}
}

:notebook:   Note that the records array accepts a maximum of 100 record ID's


What's Next

Learn how the Okra widget works

Did this page help you?