Stellar Disbursement Platform API

The Stellar Disbursement Platform (SDP) is an open-source tool built for organizations to make bulk payments to a group of recipients over the Stellar network. The REST API supports tenant management, disbursement campaigns, recipient registration, wallet management, and payment monitoring. The SDP supports multi-tenant deployments and integrates with SEP-24 for wallet onboarding.

OpenAPI Specification

stellar-disbursement-platform-api.yml Raw ↑
openapi: 3.1.0
info:
  title: Stellar Disbursement Platform API
  version: 2.1.0
  summary: The Stellar Disbursement Platform (SDP) is a tool built for organizations to make bulk payments to a group of recipients over the Stellar network.
  description: |
    The Stellar Disbursement Platform (SDP) is a tool built for organizations to make bulk payments to a group of recipients over the Stellar network.

    This is an open-source project that is built on top of the Stellar network, and the code can be found on the following repositories:

    - [stellar/stellar-disbursement-platform-backend](https://github.com/stellar/stellar-disbursement-platform-backend): This repository contains the backend and infrastructure code for the Stellar Disbursement Platform.
    - [stellar/stellar-disbursement-platform-frontend](https://github.com/stellar/stellar-disbursement-platform-frontend): This repository contains the web frontend code for the Stellar Disbursement Platform.
    - [stellar/helm-charts](https://github.com/stellar/helm-charts/tree/main/charts/stellar-disbursement-platform): This repository contains the Helm chart for deploying the Stellar Disbursement Platform using kubernetes.
  termsOfService: https://stellar.org/terms-of-service
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - url: ''
tags:
  - name: Admin
    x-displayName: Admin (Tenant Management)
    description: The Admin API oversees the management of tenants within the system, facilitating tasks such as provisioning new tenants, updating their information, and retrieving tenant data.
  - name: Authentication
    description: Authentication controls the log in/log out process for all SDP users, as well as the token refresh process. Authentication uses a JWT approach signed with an ES256 private key.
  - name: API Keys
    description: API Keys functionality allows to create access key with granular permissions and resource management.
  - name: Balances
    description: Endpoints related to balances. A balance is an amount of a particular asset held by an organization, tenant, or account.
  - name: Bridge Integration
    description: |
      Bridge integration endpoints for connecting organizations with Bridge services.

      **Integration Flow:**
      1. Organization opts into Bridge (OPTED_IN status)
      2. Complete KYC verification process via Bridge
      3. Create virtual account for USD deposits (READY_FOR_DEPOSIT status)
      4. Receive USD deposits that are automatically converted to USDC on Stellar

      **Status Description:**
      - NOT_ENABLED → Bridge service not configured
      - NOT_OPTED_IN → Organization hasn't opted in
      - OPTED_IN → Organization opted in, KYC link created
      - READY_FOR_DEPOSIT → Virtual account created, ready for deposits
      - ERROR → Integration error occurred
  - name: Disbursements
    description: Endpoints related to disbursements. A disbursement is a group of payments sent to multiple individuals at once. An SDP user with the appropriate role triggers a new disbursement through the SDP dashboard by uploading a list of receivers and amounts. When the receiver has linked their wallet to the SDP, the payment automatically begins. SDP users can track their disbursements in real-time through the SDP dashboard. Each disbursement must have a unique name defined by the organization.
  - name: Organization
    description: Organization endpoints manage the process of getting and updating organizational profile information. The organization's profile has basic information set at the time of SDP deployment. It can be modified by the Owner. Organizations can also manage their preferences, like which assets to use, through these endpoints.
  - name: Payments
    description: Endpoints related to payments. An SDP payment is an individual payment from an organization to a receiver. Each payment is part of a disbursement and occurs on the Stellar network. Granular payment status is stored in the SDP database and can be viewed in real-time on the SDP dashboard.
  - name: Profile
    description: 'Profiles endpoints manage the process of getting and updating individual profile information. Profile information is set when the account is created and can be updated by the user on the SDP dashboard Profile page. Note: profiles never refer to receivers of funds.'
  - name: Receivers
    description: |
      Endpoints related to receivers. A receiver is an individual receiving a payment in a disbursement. The receiver is tracked by phone number to reduce the need for personally identifiable information. Each receiver must be unique within the disbursement.

      Each receiver will have at least one wallet associated with them. The wallet public key will remain null until the receiver registers with a wallet provider and links the wallet to the SDP through SEP-24. Receivers must verify their identity through that process, which requires the SDP to store verification information on receivers like date of birth, national ID number, or personal PIN. This information can be updated by the organization through the receiver endpoints.
  - name: Registration
    description: |
      The registration endpoints guide the process for a receiver to verify their identity and link their wallet address to an SDP. The registration process only needs to happen once per receiver to link their wallet. Only SDP-compatible wallet providers can facilitate the registration process. These endpoints must be supported and hit by the wallet providers after the receiver gets the initial invite. After the wallet address is successfully linked, the payment automatically begins.

      There are two parts to the registration flow. First, the wallet must authenticate and initiate a registration flow using the Anchor Platform Endpoints defined below. Note that these endpoints are hosted on a different host than the Stellar Disursement Platform.

      The second part of the registration flow is handled by the webview that is opened within the wallet application. This webview uses the endpoints defined in the Stellar Disbursement Platfrom Endpoints section to complete the registration process. The wallet application can chose not to use the webview and intstead integrate directly with the API.
  - name: Statistics
    description: Statistics endpoints return general aggregated data per organization, as well as disbursement-specific metrics. SDP users can use this data to monitor their disbursements over time.
  - name: Users
    description: The users endpoints facilitate the creation of new SDP users - including setting the appropriate role, sending an email invitation, and activating a user - and managing roles.
paths:
  /login:
    post:
      tags:
        - Authentication
      summary: Log In
      description: 'Allows credentialed SDP users to log in to the SDP dashboard with a password. Note: all passwords must be at least 8 characters long and a combination of uppercase letters, lowercase letters, numbers, and symbols.'
      operationId: LogIn
      requestBody:
        content:
          '*/*':
            schema:
              required:
                - email
                - password
              type: object
              properties:
                email:
                  type: string
                password:
                  type: string
                recaptcha_token:
                  type: string
                  description: Token for reCAPTCHA validation. ReCAPTCHA token is required unless the `DISABLE_RECAPTCHA` configuration is set to true.
              example:
                email: [email protected]
                password: mysecret
        required: false
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                example:
                  token: eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoidXNlci1pZCIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicm9sZXMiOlt7Im5hbWUiOiJTdXBlcnZpc29yIn1dfSwiZXhwIjoxNjc1OTYyOTQ3fQ.4Zj9yBXch-iuFYF-kc_EhHPxjpwp_egMOLbOv4bZKO1MFvcmEgZ5MlXH1_1fZfgUxaNBcMCdRM6MGSqKocwGnA
              example:
                token: eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoidXNlci1pZCIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicm9sZXMiOlt7Im5hbWUiOiJTdXBlcnZpc29yIn1dfSwiZXhwIjoxNjc1OTYyOTQ3fQ.4Zj9yBXch-iuFYF-kc_EhHPxjpwp_egMOLbOv4bZKO1MFvcmEgZ5MlXH1_1fZfgUxaNBcMCdRM6MGSqKocwGnA
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Invalid credentials
                  extras:
                    status: 400
                    message: Invalid username or password
              example:
                error: Invalid credentials
                extras:
                  status: 400
                  message: Invalid username or password
      x-codegen-request-body-name: body
  /refresh-token:
    post:
      tags:
        - Authentication
      summary: Refresh Token
      description: A user’s token expires after 15 minutes. This endpoint handles refreshing the user’s token without disrupting their experience. It is triggered within the 30-second window before the token expires.
      operationId: RefreshToken
      responses:
        '200':
          description: Returns a new access token
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                example:
                  token: eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoidXNlci1pZCIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicm9sZXMiOlt7Im5hbWUiOiJTdXBlcnZpc29yIn1dfSwiZXhwIjoxNjc1OTYyOTQ3fQ.4Zj9yBXch-iuFYF-kc_EhHPxjpwp_egMOLbOv4bZKO1MFvcmEgZ5MlXH1_1fZfgUxaNBcMCdRM6MGSqKocwGnA
              example:
                token: eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoidXNlci1pZCIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicm9sZXMiOlt7Im5hbWUiOiJTdXBlcnZpc29yIn1dfSwiZXhwIjoxNjc1OTYyOTQ3fQ.4Zj9yBXch-iuFYF-kc_EhHPxjpwp_egMOLbOv4bZKO1MFvcmEgZ5MlXH1_1fZfgUxaNBcMCdRM6MGSqKocwGnA
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Details about the error
                  extras:
                    type: object
                    properties: {}
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Not authorized
                  extras:
                    status: 401
                    message: Not authorized
              example:
                error: Not authorized
                extras:
                  status: 401
                  message: Not authorized
      security:
        - BearerAuth: []
  /mfa:
    post:
      tags:
        - Authentication
      summary: Provide Multi-Factor Authentication
      description: Governs the multi-factor authentication process for SDP user login, including the ability to remember the device so MFA is not always required.
      operationId: authenticateMFA
      parameters:
        - name: Device-ID
          in: header
          description: Identifier of the device
          required: false
          style: simple
          explode: false
          schema:
            type: string
      requestBody:
        description: MFA request data
        content:
          '*/*':
            schema:
              required:
                - mfa_code
              type: object
              properties:
                mfa_code:
                  type: string
                  description: Multi-factor authentication code
                remember_me:
                  type: boolean
                  description: Boolean flag to remember the user
                recaptcha_token:
                  type: string
                  description: Token for reCAPTCHA validation. ReCAPTCHA token is required unless the `DISABLE_RECAPTCHA` configuration is set to true.
        required: true
      responses:
        '200':
          description: Successful authentication
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                    description: Authentication token
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Details about the error
                  extras:
                    type: object
                    properties: {}
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Not authorized
                  extras:
                    status: 401
                    message: Not authorized
              example:
                error: Not authorized
                extras:
                  status: 401
                  message: Not authorized
      x-codegen-request-body-name: body
  /forgot-password:
    post:
      tags:
        - Authentication
      summary: Forgot Password
      description: Sends an email with a token to an SDP user who has gone through the Forgot Password process.
      operationId: forgotPassword
      requestBody:
        description: Forgot password request data
        content:
          '*/*':
            schema:
              required:
                - email
              type: object
              properties:
                email:
                  type: string
                  description: Email of the user
                  format: email
                recaptcha_token:
                  type: string
                  description: Token for reCAPTCHA validation
        required: true
      responses:
        '200':
          description: Forgot password email sent successfully
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '400':
          description: Bad Request
          content:
            '*/*':
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Details about the error
                  extras:
                    type: object
                    properties: {}
      x-codegen-request-body-name: body
  /reset-password:
    post:
      tags:
        - Authentication
      summary: Reset Rassword
      description: Allows an SDP user who has gone through the Forgot Password process to set their new password with a token sent via email.
      operationId: resetPassword
      requestBody:
        description: Reset password request data
        content:
          '*/*':
            schema:
              required:
                - password
                - reset_token
              type: object
              properties:
                password:
                  type: string
                  description: New password for the user
                reset_token:
                  type: string
                  description: Token used to identify a valid password reset request
        required: true
      responses:
        '200':
          description: Password reset successfully
          content: {}
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Details about the error
                  extras:
                    type: object
                    properties: {}
      x-codegen-request-body-name: body
  /disbursements:
    get:
      tags:
        - Disbursements
      summary: List All Disbursements
      description: Fetches all disbursements the organization has created. This endpoint supports pagination. The response includes basic aggregations on payments within the disbursement.
      operationId: ListAllDisbursements
      parameters:
        - name: page
          in: query
          description: The page requested.
          required: false
          style: form
          explode: true
          schema:
            type: number
            default: 1
        - name: page_limit
          in: query
          description: Define how many results will be returned in the response.
          required: false
          style: form
          explode: true
          schema:
            type: number
            default: 20
        - name: q
          in: query
          description: A search term used to query through the disbursement names.
          required: false
          style: form
          explode: true
          schema:
            type: string
        - name: status
          in: query
          description: Comma-separated list of disbursement statuses to filter by.
          required: false
          style: form
          explode: true
          schema:
            type: string
            enum:
              - DRAFT
              - READY
              - STARTED
              - PAUSED
              - COMPLETED
          example: DRAFT
        - name: created_at_after
          in: query
          description: 'Only return disbursements that are created after this date. Format: YYYY-MM-DD'
          required: false
          style: form
          explode: true
          schema:
            type: string
          example: '2006-01-02'
        - name: created_at_before
          in: query
          description: 'Only return disbursements that are created before this date. Format: YYYY-MM-DD'
          required: false
          style: form
          explode: true
          schema:
            type: string
          example: '2006-01-02'
        - name: sort
          in: query
          description: Field used to sort disbursements
          required: false
          style: form
          explode: true
          schema:
            type: string
            default: created_at
            enum:
              - name
              - created_at
        - name: direction
          in: query
          description: Direction for sorting disbursements.
          required: false
          style: form
          explode: true
          schema:
            type: string
            default: desc
            enum:
              - asc
              - desc
      responses:
        '200':
          description: A list of Disbursement details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DisbursementPagination'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Not authorized
                  extras:
                    status: 401
                    message: Not authorized
              example:
                error: Not authorized
                extras:
                  status: 401
                  message: Not authorized
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                example:
                  error: Forbidden
              example:
                error: Forbidden
      security:
        - BearerAuth: []
    post:
      tags:
        - Disbursements
      summary: Create Disbursement
      description: 'Creates a new disbursement in  `draft ` state with basic details. Important: a disbursement is not triggered until the organization adds receivers through the Upload Disbursement Instructions endpoint and the status changes from  `draft ` to  `ready `.'
      operationId: CreateDisbursement
      requestBody:
        content:
          '*/*':
            schema:
              type: object
              properties:
                name:
                  type: string
                wallet_id:
                  type: string
                asset_id:
                  type: string
                verification_field:
                  $ref: '#/components/schemas/VerificationField'
                registration_contact_type:
                  $ref: '#/components/schemas/RegistrationContactType'
                receiver_registration_message_template:
                  type: string
              example:
                name: My New Disbursement name
                wallet_id: e2de8544-b7e2-40a9-ad40-411f70d5c4bf
                asset_id: d227a68c-2f40-11ee-be56-0242ac120002
                verification_field: DATE_OF_BIRTH
                registration_contact_type: PHONE_NUMBER
                receiver_registration_message_template: You have a payment waiting for you from {{.OrganizationName}}. Click {{.RegistrationLink}} to register.
        required: false
      responses:
        '201':
          description: A new disbursement
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Disbursement'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Bad request
                  extras:
                    status: 400
                    message: Invalid wallet provided
              example:
                error: Bad request
                extras:
                  status: 400
                  message: Invalid wallet provided
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Not authorized
                  extras:
                    status: 401
                    message: Not authorized
              example:
                error: Not authorized
                extras:
                  status: 401
                  message: Not authorized
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                example:
                  error: Forbidden
              example:
                error: Forbidden
      security:
        - BearerAuth: []
      x-codegen-request-body-name: body
  /disbursements/{id}:
    get:
      tags:
        - Disbursements
      summary: Retrieve a Disbursement
      description: Fetches information on a specific disbursement by  `id `.
      operationId: RetrieveADisbursement
      parameters:
        - name: id
          in: path
          description: ID of the `Disbursement`.
          required: true
          style: simple
          explode: false
          schema:
            type: string
      responses:
        '200':
          description: Disbursement details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Disbursement'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Not authorized
                  extras:
                    status: 401
                    message: Not authorized
              example:
                error: Not authorized
                extras:
                  status: 401
                  message: Not authorized
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                example:
                  error: Forbidden
              example:
                error: Forbidden
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  extras:
                    type: object
                    properties:
                      status:
                        type: number
                      message:
                        type: string
                example:
                  error: Not found
                  extras:
                    status: 404
                    message: Disbursement not found
              example:
                error: Not found
                extras:
                  status: 404
                  message: Disbursement not found
      security:
        - BearerAuth: []
    delete:
      tags:
        - Disbursements
      summary: Deletes a Draft Disbursement
      description: Deletes a Disbursement in Draft or Ready Status by `id`.
      operationId: DeleteADisbursement
      parameters:
        - name: id
          in: path
          description: ID of the `Disbursement`.
          required: true
          style: simple
          explode: false
          schema:
            type: string
      responses:
        '200':
          description: Deleted Disbursement details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Disbursement'
        '400':
          description: Bad Request, Cannot delete a disbursement that has started
          $ref: '#/components/responses/BadRequestResponse'
        '401':
          description: Unauthorized
          $ref: '#/components/responses/UnauthorizedResponse'
        '403':
          description: Forbidden
          $ref: '#/components/responses/ForbiddenResponse'
        '404':
          description: Not Found
          $ref: '#/components/responses/NotFoundResponse'
      security:
        - BearerAuth: []
  /disbursements/{id}/receivers:
    get:
      tags:
        - Disbursements
      summary: List All Disbursement Receivers
      description: Fetches a list of receivers within a specific disbursement using the disbursement  `id `. This endpoint supports pagination and sorting.
      operationId: ListAllDisbursementReceivers
      parameters:
        - name: id
          in: path
          description: ID of the Disbursement
          required: true
          style: simple
          explode: false
          schema:
            type: string
        - name: page
          in: query
          description: The page number to fetch.
          required: false
          style: form
          explode: true
          schema:
            type: number
            default: 1
        - name: page_limit
          in: query
          description: The number of records to return per page.
          required: false
          style: form
          explode: true
          schema:
            type: number
            default: 20
        - name: sort
          in: query
          description: Field used to sort receivers
          required: false
          style: form
          explode: true
          schema:
            type: string
            default: updated_at
            enum:
              - updated_at
              - created_at
        - name: direction
          in: query
          description: Direction for sorting receivers.
          required: false
          style: form
          explode: true
          schema:
            type: string
            default: desc
            enum:
              - asc
              - desc
      responses:
        '200':
          description: A list of Disbursement Receivers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DisbursementReceiverPagination'
        '401':
          description: Unauthorized
          $ref: '#/components/responses/UnauthorizedResponse'
        '403':
          description: Forbidden
          $ref: '#/components/responses/ForbiddenResponse'
        '404':
          description: Not Found
          $ref: '#/components/responses/NotFoundResponse'
      security:
        - BearerAuth: []
  /disbursements/{id}/instructions:
    get:
      tags:
        - Disbursements
      summary: Download Disbursement Instructions
      description: Allows an SDP user to download the raw CSV file that was uploaded when creating the disbursement. This will only return results after instructions have been attached to a draft disbursement.
      operationId: DownloadDisbursementInstructions
      parameters:
        - name: id
          in: path
          description: ID of the Disbursement
          required: true
          style: simple
          explode: false
          schema:
            type: string
      responses:
        '200':
          description: Disbursement CSV file
          headers:
            Content-Disposition:
              description: The filename of the returned CSV file.
              style: simple
              explode: false
              schema:
                type: string
            Content-Type:
              description: text/csv
              style: simple
              explode: false
              schema:
                type: string
          content:
            text/csv:
              example: ''
        '400':
          description: Bad request, invalid request parameters
          $ref: '#/components/responses/BadRequestResponse'
        '401':
          description: Unauthorized
          $ref: '#/components/responses/UnauthorizedResponse'
        '403':
          description: Forbidden
          $ref: '#/components/responses/ForbiddenResponse'
      

# --- truncated at 32 KB (212 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/stellar/refs/heads/main/openapi/stellar-disbursement-platform-api.yml