openapi: 3.0.0
info:
  title: Curacel Pay Developer API
  description: "Welcome to the Curacel Pay API Reference! \nThis API is designed to
    streamline and enhance your health insurance processing experience.\n\nWith these
    API endpoints, you would be able to create payments resources on our platform.\n\nThese
    can be used by\n\n- EMR (electronic medical records) systems to submit payments
    to health insurers (HMOs)\n- Health insurer ERPs to push payments to Curacel for
    auto adjudication\n"
  contact:
    email: support@curacel.ai
  license:
    name: Curacel Terms And Agreement
    url: https://curacel.co/terms-and-conditions.php
  version: 1.0.0
servers:
- url: https://pay.curacel.co/api/v1
  description: Production
- url: https://sandbox.pay.curacel.co/api/v1
  description: Sandbox
paths:
  "/beneficiaries":
    post:
      tags:
      - Beneficiaries
      summary: Create a new beneficiary
      description: Create a new beneficiary with bank account details
      operationId: createBeneficiary
      requestBody:
        description: Beneficiary details
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - bank_name
              - bank_code
              - account_number
              - name
              - beneficiary_type
              properties:
                email:
                  type: string
                  format: email
                  nullable: true
                  description: Email address of the beneficiary
                bank_name:
                  type: string
                  minLength: 3
                  description: Name of the bank
                bank_code:
                  type: string
                  description: Bank code identifier
                account_number:
                  type: string
                  description: Bank account number
                name:
                  type: string
                  minLength: 3
                  description: Full name of the beneficiary
                beneficiary_type:
                  type: string
                  enum:
                  - I
                  - B
                  description: Type of beneficiary (I for Individual, B for Business)
                business_name:
                  type: string
                  minLength: 3
                  nullable: true
                  description: Name of the business (required if beneficiary_type
                    is B)
                contact_name:
                  type: string
                  minLength: 3
                  nullable: true
                  description: Name of the contact person
                contact_email:
                  type: string
                  format: email
                  nullable: true
                  description: Email of the contact person
                contact_phone:
                  type: string
                  nullable: true
                  description: Phone number of the contact person
      responses:
        '201':
          description: Beneficiary created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  account_number:
                    type: string
                  bank_name:
                    type: string
                  bank_code:
                    type: string
                  name:
                    type: string
                  email:
                    type: string
                    format: email
                  updated_at:
                    type: string
                    format: date-time
                  created_at:
                    type: string
                    format: date-time
                  id:
                    type: integer
        '422':
          description: Validation error
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
  "/payment-links":
    post:
      tags:
      - Payment Links
      summary: Create a new payment link
      description: Create a new payment link for receiving payments
      operationId: createPaymentLink
      requestBody:
        description: Payment link details
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - purpose
              properties:
                purpose:
                  type: string
                  maxLength: 255
                  description: Purpose of the payment link
                amount:
                  type: number
                  minimum: 0
                  nullable: true
                  description: Amount to be paid (optional)
                description:
                  type: string
                  maxLength: 255
                  nullable: true
                  description: Additional description for the payment link
      responses:
        '200':
          description: Payment link created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      public_url:
                        type: string
                        description: Public URL for the payment link
                      is_active:
                        type: boolean
                        description: Payment link status
                  message:
                    type: string
        '401':
          description: Unauthorized
        '403':
          description: Forbidden - Feature not enabled or unauthorized action
        '422':
          description: Validation error
  "/create-payout":
    post:
      tags:
      - Payouts
      summary: Create a new payout
      description: Create a new payout for a beneficiary
      operationId: createPayout
      requestBody:
        description: Payout details
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - amount
              - narration
              - category
              - beneficiary
              properties:
                amount:
                  type: number
                  format: decimal
                  minimum: 1
                  description: Amount to be paid (decimal with 2 decimal places)
                narration:
                  type: string
                  minLength: 3
                  description: Purpose of the payout
                category:
                  type: string
                  enum:
                  - claims
                  - operations
                  - salary
                  - equipment
                  - appliance
                  - other
                  description: Payment category
                description:
                  type: string
                  minLength: 3
                  nullable: true
                  description: Additional description for the payout
                beneficiary:
                  type: integer
                  description: ID of the beneficiary (must exist in payer_beneficiaries)
                schedule_time:
                  type: string
                  format: date-time
                  nullable: true
                  description: Future date/time to schedule the payout (must be after
                    current time)
      responses:
        '201':
          description: Payout created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      amount:
                        type: number
                        format: decimal
                      fee:
                        type: number
                        format: decimal
                      status:
                        type: integer
                        enum:
                        - 0
                        - 1
                        - 2
                        - 3
                        - 4
                        - 5
                        - 6
                        - 7
                        - 8
                        - 9
                        - 10
                        description: |
                          Payment status:
                          0 - Pending
                          1 - Successful
                          2 - Awaiting Approval
                          3 - Failed
                          4 - Rejected
                          5 - Processing
                          6 - Approved
                          7 - Draft
                          8 - Awaiting Payment
                          9 - Failed Retry Pending
                          10 - Failed Retrying
                      status_text:
                        type: string
                      category:
                        type: string
                        enum:
                        - claims
                        - operations
                        - salary
                        - equipment
                        - appliance
                        - other
                      narration:
                        type: string
                      description:
                        type: string
                        nullable: true
                      description_short:
                        type: string
                      scheduled_for:
                        type: string
                        format: date-time
                        nullable: true
                      initiated_at:
                        type: string
                        format: date-time
                        nullable: true
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      can_be_retried:
                        type: boolean
                      total_amount:
                        type: number
                        format: decimal
        '422':
          description: Validation error
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
  "/invoices":
    post:
      tags:
      - Invoices
      summary: Create a new invoice
      description: Create a new invoice for a customer with optional draft status
      operationId: createInvoice
      requestBody:
        description: Invoice details
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - items
              - due_date
              - currency
              - customer
              properties:
                items:
                  type: array
                  items:
                    type: object
                    required:
                    - description
                    - qty
                    - price
                    properties:
                      description:
                        type: string
                        minLength: 3
                        description: Description of the item
                      qty:
                        type: integer
                        minimum: 1
                        description: Quantity of the item
                      price:
                        type: number
                        minimum: 0
                        exclusiveMinimum: true
                        description: Price per unit
                due_date:
                  type: string
                  format: date
                  description: Due date for the invoice
                currency:
                  type: string
                  minLength: 3
                  description: Currency code for the invoice (only NGN is supported
                    currently)
                  enum:
                  - NGN
                customer:
                  type: object
                  required:
                  - email
                  - name
                  properties:
                    email:
                      type: string
                      format: email
                      description: Customer's email address
                    name:
                      type: string
                      minLength: 3
                      description: Customer's full name
                    phone_number:
                      type: string
                      minLength: 3
                      nullable: true
                      description: Customer's phone number
                discount_type:
                  type: string
                  enum:
                  - percentage
                  - fixed
                  nullable: true
                  description: Type of discount to apply
                discount_value:
                  type: number
                  minimum: 0
                  nullable: true
                  description: Value of the discount
                vat_percent:
                  type: number
                  minimum: 0
                  maximum: 100
                  nullable: true
                  description: VAT percentage to apply
                additional_info:
                  type: string
                  nullable: true
                  description: Additional information to add to the invoice e.g payment
                    details, additional instructions etc
                cc_emails:
                  type: array
                  maxItems: 10
                  nullable: true
                  items:
                    type: string
                    format: email
                  description: List of CC email addresses
                title:
                  type: string
                  minLength: 3
                  nullable: true
                  description: Title of the invoice
                save_as_draft:
                  type: boolean
                  nullable: true
                  description: Whether to save the invoice as a draft
      responses:
        '201':
          description: Invoice created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      subtotal:
                        type: number
                        description: Subtotal amount before discounts and VAT
                      total:
                        type: number
                        description: Total amount after discounts and VAT
                      discount:
                        type: number
                        description: Discount amount applied
                      vat:
                        type: number
                        description: VAT amount
                      vat_percent:
                        type: number
                        description: VAT percentage applied
                      reference:
                        type: string
                        description: Unique reference for the invoice
                      invoice_number:
                        type: string
                        description: Invoice number
                      created_at:
                        type: string
                        format: date-time
                        description: Creation timestamp
                      is_draft:
                        type: boolean
                        description: Whether the invoice is saved as a draft
        '422':
          description: Validation error
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
  "/transactions":
    get:
      tags:
      - Transactions
      summary: List wallet transactions
      description: 'Fetch a paginated list of wallet transactions for the authenticated
        payer with optional filters. Results include transaction morph data and derived
        fields like category, reference, and narration.

'
      operationId: listTransactions
      parameters:
      - name: type
        in: query
        description: Filter by transaction direction (maps to action dr/cr)
        schema:
          type: string
          enum:
          - debit
          - credit
      - name: category
        in: query
        description: Filter by high-level category
        schema:
          type: string
          enum:
          - invoice
          - payout
      - name: reference
        in: query
        description: Filter by reference (exact or partial match depending on server
          implementation)
        schema:
          type: string
      - name: status
        in: query
        description: Filter by transaction status
        schema:
          type: string
          enum:
          - pending
          - success
          - failed
      - name: amount
        in: query
        description: Filter by amount (>= 0)
        schema:
          type: number
          minimum: 0
      - name: start_date
        in: query
        description: Start date (ISO 8601, e.g. 2025-11-01)
        schema:
          type: string
          format: date
      - name: end_date
        in: query
        description: End date (ISO 8601, must be >= start_date)
        schema:
          type: string
          format: date
      - name: page
        in: query
        description: Page number
        schema:
          type: integer
          minimum: 1
          default: 1
      - name: per_page
        in: query
        description: Items per page
        schema:
          type: integer
          enum:
          - 10
          - 20
          - 50
          - 100
          default: 20
      responses:
        '200':
          description: Paginated list of wallet transactions
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/TransactionsPage"
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '422':
          description: Validation error
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API KEY from your account dashboard
  schemas:
    TransactionMorph:
      type: object
      description: Transaction entity. Fields vary depending on transaction_type.
      additionalProperties: true
    WalletTransaction:
      type: object
      properties:
        id:
          type: integer
        amount:
          type: string
        currency:
          type: string
        transaction_type:
          type: string
        transaction_id:
          type: integer
        action:
          type: string
          enum:
          - dr
          - cr
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        category:
          type: string
        reference:
          type: string
          nullable: true
        narration:
          type: string
        transaction:
          "$ref": "#/components/schemas/TransactionMorph"
    PaginatorLink:
      type: object
      properties:
        url:
          type: string
          nullable: true
        label:
          type: string
        active:
          type: boolean
    TransactionsPage:
      type: object
      properties:
        current_page:
          type: integer
        data:
          type: array
          items:
            "$ref": "#/components/schemas/WalletTransaction"
        first_page_url:
          type: string
        from:
          type: integer
          nullable: true
        last_page:
          type: integer
        last_page_url:
          type: string
        links:
          type: array
          items:
            "$ref": "#/components/schemas/PaginatorLink"
        next_page_url:
          type: string
          nullable: true
        path:
          type: string
        per_page:
          type: integer
        prev_page_url:
          type: string
          nullable: true
        to:
          type: integer
          nullable: true
        total:
          type: integer
security:
- bearerAuth: []
