> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chip-in.asia/llms.txt
> Use this file to discover all available pages before exploring further.

# List all webhooks

> Returns a list of previously created webhooks.

*Please note that this request is cached and will refresh every hour.*




## OpenAPI

````yaml _openapi-chip-send GET /webhooks
openapi: 3.1.0
info:
  description: >

    The CHIP Send API enables merchants to send funds programmatically via a
    REST API and to register recipient bank accounts for payouts.


    All endpoints share a single base URL and a single authentication scheme.
    This page covers everything required to make a successful request.


    ## Endpoints


    The base URL must match the merchant's environment:


    | Environment | Base URL                                  |

    |-------------|-------------------------------------------|

    | Staging     | `https://staging-api.chip-in.asia/api/v1` |

    | Production  | `https://api.chip-in.asia/api/v1`         |


    The operation path from the [API reference](#) (for example `/send/accounts`
    or `/send/send_instructions`) is appended to the base URL.


    ## Prerequisites


    Before integration begins, a CHIP Send account must be created for the
    merchant by the CHIP admin team. To obtain credentials, the merchant's CHIP
    Account Manager must be contacted with the following information:

      1. A primary email address.
      2. The email addresses of every required approver. If two approvals are required, both email addresses must be provided.

    ## Credentials


    Two pieces of information are issued to the merchant:


    | Credential       | Where it goes                                         
    | What it
    does                                                                       |

    |------------------|--------------------------------------------------------|------------------------------------------------------------------------------------|

    | **API Key**      | `Authorization: Bearer <API Key>` header              
    | Identifies the merchant's account. Sent on every
    request.                          |

    | **API Secret**   | Never sent over the network. Used only for signing.   
    | Used to compute the per-request checksum. Must be stored securely, like a
    password. |


    The API Key and the `api_key` value used inside the checksum string are the
    **same value**.


    The API Secret is **never** transmitted in any request. It only ever lives
    on the merchant's server and is used to compute the checksum described
    below.


    Both the API Key and the API Secret are available to the merchant in the
    [CHIP Control → Settings →
    Applications](https://portal.chip-in.asia/control/settings/applications)
    page of the merchant portal.


    ## How authentication works


    Every request to the CHIP Send API must include three headers:


    | Header          |
    Value                                                                                
    |

    |-----------------|---------------------------------------------------------------------------------------|

    | `Authorization` | `Bearer <API
    Key>`                                                                    |

    | `epoch`         | The current Unix timestamp in seconds (for example,
    `1689826456`)                     |

    | `checksum`      | Hex-encoded HMAC-SHA512 of the signing string, computed
    with the API Secret           |


    The `epoch` value must be within **30 seconds** of the server's clock. If it
    is too old or too far in the future, the request is rejected as
    `Unauthorized`. The merchant's server clock must therefore be synchronised
    (for example via NTP).


    ## How to compute the checksum


    The signing string is formed by **concatenating the `epoch` value and the
    API Key with no separator, in that order**:


    ```

    signing_string = <epoch> + <API Key>

    ```


    For example, with `epoch = 1689826456` and `API Key =
    e0645c9e-fcf2-4f29-a327-202f7ed3d969`:


    ```

    1689826456e0645c9e-fcf2-4f29-a327-202f7ed3d969

    ```


    The checksum is then computed as:


    ```

    checksum = HEX( HMAC_SHA512( key = API Secret, message = signing_string ) )

    ```


    Given `API Secret = a118729e-4243-4145-83b3-0b8cb213fe8e`, the checksum for
    the example signing string above is:


    ```

    45bee62dba8087ab1e7e767d92f8d6e26f8bd19ee5fd2fef6386bb9425976498a86ffdbddb7a49919998e993c20626196ea652320f438a9528d2b8c9d19ec266

    ```


    This expected value can be used to verify the implementation before any real
    request is sent.


    ## A complete request


    The following `curl` example computes the epoch and checksum, then sends a
    request end-to-end:


    ```bash

    # 1. Compute the epoch and checksum (must be recomputed for every request)

    EPOCH=$(date +%s)

    API_KEY="e0645c9e-fcf2-4f29-a327-202f7ed3d969"

    API_SECRET="a118729e-4243-4145-83b3-0b8cb213fe8e"

    CHECKSUM=$(printf '%s%s' "$EPOCH" "$API_KEY" | openssl dgst -sha512 -hmac
    "$API_SECRET" -hex | sed 's/^.*= //')


    # 2. Send the request

    curl -X POST "https://staging-api.chip-in.asia/api/v1/send/bank_accounts" \
      -H "Authorization: Bearer $API_KEY" \
      -H "epoch: $EPOCH" \
      -H "checksum: $CHECKSUM" \
      -H "Content-Type: application/json" \
      -d '{
        "account_number": "157380112229",
        "bank_code": "MBBEMYKL",
        "name": "Ahmad Razali",
        "reference": "VENDOR-EMP-001"
      }'
    ```


    A `200 OK` response confirms that authentication is working correctly. For
    other responses, see [Troubleshooting](#troubleshooting) below.


    ## Language examples


    The same computation in four common languages:


    <CodeGroup>


    ```javascript Node.js

    const crypto = require('crypto');


    const epoch = Math.floor(Date.now() / 1000).toString();

    const apiKey = process.env.CHIP_API_KEY;

    const apiSecret = process.env.CHIP_API_SECRET;


    const signingString = epoch + apiKey;

    const checksum = crypto
      .createHmac('sha512', apiSecret)
      .update(signingString)
      .digest('hex');

    // Then send the request with headers:

    //   Authorization: Bearer <apiKey>

    //   epoch: <epoch>

    //   checksum: <checksum>

    ```


    ```ruby Ruby

    require 'openssl'


    epoch = Time.now.to_i.to_s

    api_key = ENV['CHIP_API_KEY']

    api_secret = ENV['CHIP_API_SECRET']


    signing_string = "#{epoch}#{api_key}"

    checksum = OpenSSL::HMAC.hexdigest('SHA512', api_secret, signing_string)


    # Then send the request with headers:

    #   Authorization: Bearer <api_key>

    #   epoch: <epoch>

    #   checksum: <checksum>

    ```


    ```python Python

    import hashlib, hmac, time


    epoch = str(int(time.time()))

    api_key = "YOUR_API_KEY"

    api_secret = "YOUR_API_SECRET"


    signing_string = (epoch + api_key).encode()

    checksum = hmac.new(api_secret.encode(), signing_string,
    hashlib.sha512).hexdigest()


    # Then send the request with headers:

    #   Authorization: Bearer <api_key>

    #   epoch: <epoch>

    #   checksum: <checksum>

    ```


    ```php PHP

    <?php

    $epoch = (string) time();

    $apiKey = getenv('CHIP_API_KEY');

    $apiSecret = getenv('CHIP_API_SECRET');


    $signingString = $epoch . $apiKey;

    $checksum = hash_hmac('sha512', $signingString, $apiSecret);


    // Then send the request with headers:

    //   Authorization: Bearer <apiKey>

    //   epoch: <epoch>

    //   checksum: <checksum>

    ```


    </CodeGroup>


    ## Troubleshooting


    | Symptom                                                | Most likely
    cause                                                                                                                                                                                                               
    |

    |--------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

    | `401 Unauthorized` with no further detail              | The `epoch` value
    is more than 30 seconds off the server clock, or the merchant's server clock
    is incorrect. NTP synchronisation should be
    verified.                                                                             
    |

    | `401 Unauthorized` with a checksum-related error       | The signing
    string is wrong. The following should be verified: (a) it is `<epoch> +
    <apiKey>` with **no separator**, (b) the message is the *string* (not a JSON
    object), (c) the output is **hex-encoded** (not base64), (d) SHA-512 is used
    (not SHA-256). |

    | `401 Unauthorized` with an `Authorization`-related error | The
    `Authorization: Bearer <API Key>` header is missing, malformed, or the API
    Key is
    invalid.                                                                                                                                     
    |

    | `400 Bad Request` on a syntactically valid payload     | The `epoch` or
    `checksum` header is missing, or one of the values contains an unexpected
    character.                                                                                                                             
    |

    | A request works in Postman but fails from the merchant's code | The
    checksum is being computed once and reused across requests. The checksum
    must be **recomputed for every request** with a fresh
    `epoch`.                                                                             
    |


    ## Basic integration flow


    A complete payout consists of four steps:

      1. The [Accounts API](/chip-send/api-reference/accounts/list) is called to check the convertible balance.
      2. The [Increase Send Limit API](/chip-send/api-reference/send-limits/create) is called to allocate balance for payouts.
      3. The [Add Bank Account API](/chip-send/api-reference/bank-accounts/create) is called to register a recipient.
      4. The [Create Send Instruction API](/chip-send/api-reference/send-instructions/create) is called to send funds.

    A walkthrough is provided in [Test
    Integration](/chip-send/api-reference/test-integration).


    ## Approving CHIP Send Budget Allocation requests


    Every approver receives an email when a budget-allocation request requires
    approval. Approval is performed by clicking the **Approve** button in the
    email. Once all required approvers have approved, the new balance is
    reflected in the [Accounts API](/chip-send/api-reference/accounts/list)
    response.


    The token used in the `Authorization` header is the **API Key** mentioned in
    the Credentials section above.
  version: 1.0.1
  title: CHIP Send API
  termsOfService: https://www.chip-in.asia/terms-of-service
  contact:
    name: CHIP
    url: https://www.chip-in.asia
servers:
  - description: Sandbox
    url: https://staging-api.chip-in.asia/api
  - description: Production
    url: https://api.chip-in.asia/api
security:
  - bearerAuth: []
tags:
  - name: Accounts
    description: >-
      Endpoint for retrieving CHIP Send account information. Depending on your
      account agreement, you may only have one account.
  - name: Send Limits
    description: >
      Send Limit records incoming transactions (converted from collection —
      `transaction_type: in`) and outgoing transactions (sent to recipient —
      `transaction_type: out`) in CHIP Send.


      To be able to send funds to third parties, you must have balance in your
      CHIP Send Account. Use the Increase CHIP Send Budget Allocation API to
      convert settlement (collection) amounts into the Send Limit.


      Please note that in the Staging / UAT environment, your convertible
      collection amount is set to MYR 1,000.00. In production, it will reflect
      your actual upcoming settlement amount.
  - name: Bank Accounts
    description: Endpoint for managing recipient bank account details.
  - name: Send Instructions
    description: >-
      Endpoint for performing send instructions. This is the main API for
      sending funds with CHIP Send.
  - name: Groups
    description: Endpoints for managing groups of company bank accounts.
  - name: Webhooks
    description: >-
      Endpoints for managing webhook events used for server-to-server
      notifications.
paths:
  /webhooks:
    get:
      tags:
        - Webhooks
      summary: List all webhooks
      description: |
        Returns a list of previously created webhooks.

        *Please note that this request is cached and will refresh every hour.*
      operationId: webhooks_index
      parameters:
        - name: epoch
          in: header
          description: Unix epoch timestamp
          required: true
          schema:
            allOf:
              - $ref: '#/components/schemas/UnixTimestamp'
        - name: checksum
          in: header
          description: Refer to checksum calculation
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/Webhook'
              example:
                results:
                  - id: 1
                    name: Send Instruction Notifications
                    public_key: >-
                      -----BEGIN PUBLIC KEY-----

                      MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA6gLlBKxCB5dxPJbinCzl

                      hOfKSgQtOWQQBxmnWIkEVUbqhpnqr3xNYiAvDyMUxYUwuzN44eHO+mR9MZWcSx3c

                      bXmKa3gsOzR6GdcOxMGaVxvfje+fujCAlCtO1BP+A9/FS3KcPgCYG1wtAPwA5IAf

                      HylL3TsUVIJQFBgiBr6N4Bgapr9eloaFfeYIBRsXmxPKAMJivqxYpLh0V3N4ZFd5

                      TGqSEAa4b1ULDr6p0sB2L3QikTdsF0zp03zNceKA6fXDOzD0xWtg9buXvyKwePK4

                      M2kcnWBNfsWghrdg0fG3O9bmkaS1oEXydrmJfuiI8h6a64J/1nzooi2yLC9D6Ta0

                      S63bbuAHymnQtiNuV7Ixp6IoTGFaS88aTiHaP8rdyWV8JTDFx0qeDzyaGWiYGwEF

                      mj/buHCEcRhoajbGkPhYA4YEdn4jy1wZhEr2OMdBPM7mPPI0Hy3hcNJVMVVlrpHe

                      IltQATpjlNaJMlRPjbcaiW7dsO3BuF9ZOMGksSOnyYm/AgMBAAE=

                      -----END PUBLIC KEY-----
                    callback_url: https://api.merchant.example/webhooks/chip-send
                    email: webhooks@example.com
                    event_hooks:
                      - bank_account_status
                      - budget_allocation_status
                      - send_instruction_status
                    created_at: '2024-06-15T08:00:00.000Z'
                    updated_at: '2024-06-15T08:00:00.000Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/UnauthorizedAction'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  schemas:
    UnixTimestamp:
      type: integer
      description: Unix timestamp (seconds).
      format: int64
      example: 1619740800
    Webhook:
      type: object
      description: A webhook subscription that delivers event notifications to your server.
      properties:
        id:
          type: integer
          format: int64
          example: 1
        name:
          type: string
          minimum: 1
          maximum: 256
        public_key:
          readOnly: true
          allOf:
            - $ref: '#/components/schemas/PublicKey'
        callback_url:
          allOf:
            - $ref: '#/components/schemas/URL'
        email:
          type: string
          format: email
        event_hooks:
          type: array
          minItems: 1
          uniqueItems: true
          description: List of events to trigger webhook callbacks for.
          items:
            $ref: '#/components/schemas/Event'
        created_at:
          readOnly: true
          description: Object creation time in UTC.
          type: string
          format: date-time
        updated_at:
          readOnly: true
          description: Object updated time in UTC.
          type: string
          format: date-time
    PublicKey:
      type: string
      description: >-
        PEM-encoded RSA public key for authenticating webhook or callback
        payloads
      readOnly: true
      example: |-
        -----BEGIN PUBLIC KEY-----
        MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA6gLlBKxCB5dxPJbinCzl
        hOfKSgQtOWQQBxmnWIkEVUbqhpnqr3xNYiAvDyMUxYUwuzN44eHO+mR9MZWcSx3c
        bXmKa3gsOzR6GdcOxMGaVxvfje+fujCAlCtO1BP+A9/FS3KcPgCYG1wtAPwA5IAf
        HylL3TsUVIJQFBgiBr6N4Bgapr9eloaFfeYIBRsXmxPKAMJivqxYpLh0V3N4ZFd5
        TGqSEAa4b1ULDr6p0sB2L3QikTdsF0zp03zNceKA6fXDOzD0xWtg9buXvyKwePK4
        M2kcnWBNfsWghrdg0fG3O9bmkaS1oEXydrmJfuiI8h6a64J/1nzooi2yLC9D6Ta0
        S63bbuAHymnQtiNuV7Ixp6IoTGFaS88aTiHaP8rdyWV8JTDFx0qeDzyaGWiYGwEF
        mj/buHCEcRhoajbGkPhYA4YEdn4jy1wZhEr2OMdBPM7mPPI0Hy3hcNJVMVVlrpHe
        IltQATpjlNaJMlRPjbcaiW7dsO3BuF9ZOMGksSOnyYm/AgMBAAE=
        -----END PUBLIC KEY-----
    URL:
      type: string
      format: url
      example: https://api.merchant.example/webhooks/chip-send
      maxLength: 500
    Event:
      type: string
      description: >-
        Available event types and when they are emitted:


        `bank_account_status`: Emitted when a company bank account's status
        changes. This occurs when CHIP processes the bank account for
        verification.


        ---


        `budget_allocation_status`: Emitted when a budget allocation's status
        changes. This occurs when an approver approves the increment.


        ---


        `send_instruction_status`: Emitted when a company send instruction's
        status changes. This occurs when CHIP processes the instruction with the
        bank.


        ---
      enum:
        - bank_account_status
        - budget_allocation_status
        - send_instruction_status
    BadRequestResponse:
      type: object
      properties:
        message:
          type: string
          example: Bad request
        code:
          type: number
          example: 400
        data:
          type: object
          example: {}
    UnauthorizedResponse:
      type: object
      properties:
        message:
          type: string
          example: Unauthorized
        code:
          type: number
          example: 401
        data:
          type: object
          example: {}
    UnauthorizedActionResponse:
      type: object
      properties:
        message:
          type: string
          example: You are not authorized to perform this action
        code:
          type: number
          example: 403
        data:
          type: object
          example: {}
    NotFoundResponse:
      type: object
      properties:
        message:
          type: string
          example: Record not found
        code:
          type: number
          example: 404
        data:
          type: object
          example: {}
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BadRequestResponse'
    Unauthorized:
      description: Unauthorized request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UnauthorizedResponse'
    UnauthorizedAction:
      description: Unauthorized action request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UnauthorizedActionResponse'
    NotFound:
      description: Record not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/NotFoundResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````