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

# Rotate the signing secret

> Replaces the endpoint's signing secret and returns the new one. The secret is
shown only in this response and cannot be retrieved afterwards.

Deliveries are signed with the new secret immediately, so any delivery still in
flight under the old secret will fail your verification until you deploy the new
one. **Requires scope `webhooks`.**




## OpenAPI

````yaml /openapi.yaml post /merchant/api/webhooks/{id}/rotate-secret
openapi: 3.1.0
info:
  title: Kori Merchant API
  version: 1.0.0
  description: >
    The Kori Merchant API lets your application collect and disburse
    mobile-money

    payments across Mali (Orange Money, Wave, Moov) and manage payouts,

    beneficiaries, bulk payments, payment links, your team, webhooks and
    settings.


    All amounts are in **XOF** (West African CFA franc), the currency the Mali

    mobile-money operators settle in. XOF has no minor unit, so an amount of
    5000 is

    5 000 francs, not cents. `currency` defaults to `XOF`.


    Minimums differ by direction: **100 XOF** to collect a payment, **1000 XOF**
    to send

    one (payouts, bulk pay and `/deposit`).


    Every endpoint documented here is reachable with a **merchant API key**. You

    exchange your API key + secret for a short-lived **Bearer token** scoped to
    a set

    of permissions, then call the rest of the API with that token. The scopes
    you can

    grant are exactly the ones shown in the **API Keys** screen of your Kori
    dashboard.


    ## Authentication flow

    1. `POST /merchant/api/auth` with `X-API-Key` and `X-API-Secret` headers.
    Optionally
       request a subset of `scopes` and an expiry (`expires_in_hours`, 1–720).
    2. Use the returned `data.token` as `Authorization: Bearer <token>` on every
    other call.

    3. Each endpoint requires a specific scope; a token missing that scope gets
    `403`.


    ## Response envelope

    All responses share the shape `{ "success": boolean, "message"?: string,

    "request_id"?: string, "data"?: object }`. Errors set `success: false` and a

    human-readable `message`.


    ## Asynchronous payments

    `POST /merchant/api/pay` returns `202` with `status: "pending"` — the
    customer has

    only been *prompted*. Wait for the `payment_received` webhook (or poll the

    transaction) before treating a collection as paid. Never rely on the HTTP
    response

    alone to mark an order complete.
  contact:
    name: Kori Support
    url: https://kori.ml
servers:
  - url: https://dev.kori.ml
    description: Live
  - url: https://sandbox.kori.ml
    description: Sandbox — simulated payments, no money moves
security:
  - BearerAuth: []
tags:
  - name: Authentication
    description: Exchange your API key + secret for a scoped Bearer token.
  - name: Payments
    description: >-
      Collect from customers (`pay`), disburse (`deposit`), check balance and
      transactions.
  - name: Payouts
    description: Withdraw your balance to mobile money or bank accounts.
  - name: Beneficiaries
    description: Saved payout recipients.
  - name: Payment Links
    description: Shareable hosted payment pages.
  - name: Bulk Pay
    description: Batch disbursements to many recipients.
  - name: Team
    description: Manage dashboard team members and roles.
  - name: Webhooks
    description: Register endpoints to receive event notifications.
  - name: Settings
    description: Merchant account preferences.
paths:
  /merchant/api/webhooks/{id}/rotate-secret:
    post:
      tags:
        - Webhooks
      summary: Rotate the signing secret
      description: >
        Replaces the endpoint's signing secret and returns the new one. The
        secret is

        shown only in this response and cannot be retrieved afterwards.


        Deliveries are signed with the new secret immediately, so any delivery
        still in

        flight under the old secret will fail your verification until you deploy
        the new

        one. **Requires scope `webhooks`.**
      parameters:
        - $ref: '#/components/parameters/PathId'
      responses:
        '200':
          description: A new secret was issued.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          id:
                            type: integer
                            example: 17
                          secret:
                            type: string
                            description: The new signing secret. Shown once.
                            example: >-
                              9f2b7c1e4a8d05f3b6c9e2a7d41b8e6039c5a2f7d8b1e4c6a9f0b3d7e2c8a15
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  parameters:
    PathId:
      name: id
      in: path
      required: true
      schema:
        type: integer
  schemas:
    Envelope:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
        request_id:
          type: string
          format: uuid
    Error:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          example: Invalid or missing parameter
        request_id:
          type: string
          format: uuid
  responses:
    Unauthorized:
      description: Missing, invalid, or expired Bearer token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Token lacks the required scope (or IP not whitelisted).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Scoped Bearer token from `POST /merchant/api/auth`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.