PayMore logo
API Reference · v1

Paymore Developer API

Verify end users, issue cards and move funds programmatically with the Paymore REST API. All requests and responses use JSON over HTTPS.

Getting Started

Getting Access

API access is available to approved business accounts only. There is no self-serve key: every key is issued after a compliance review.

STEP 1

Create an account

Sign up for a PayMore account.

Sign up
STEP 2

Apply for Business

Submit your company details from your dashboard for compliance review.

Apply
STEP 3

Receive your key

Once approved, the PayMore team issues your live API key. Active keys are listed in the Business Portal.

Business Portal

Authentication

Authenticate by sending your key in the X-API-Key header. The Authorization: Bearer header is also accepted. Live keys start with pm_live_. Endpoints marked Public do not require a key.

curl "https://api.paymore.io/v1/balance" \
  -H "X-API-Key: pm_live_xxxxxxxxxxxxxxxx"

Keys carry full access to your business balance. Use them only from your servers, never in browser or mobile code. If a key is exposed, contact PayMore support to revoke it and issue a new one.

Base URL

All endpoint paths below are relative to:

https://api.paymore.io/v1

A GET on the base URL returns the API version and the list of available endpoints.

Rate Limits

Authenticated requests are limited per business account over a rolling 60-second window:

PlanRequests / minute
Startup60
Enterprise300
Premium300

Exceeding the limit returns 429 with a Retry-After header.

Account

List plans

GET/plansPublic

Returns every business plan with its complete fee schedule. Amounts are in USD; fields ending in _pct are percentages.

Example request

curl "https://api.paymore.io/v1/plans"

Response200

{
  "plans": [
    {
      "plan": "startup",
      "monthly_fee": 500,
      "card_issuance_fee": 10,
      "card_funding_fee_pct": 2,
      "card_funding_fee_min": 0.5,
      "monthly_maintenance_fee": 1,
      "decline_fee": 0.4,
      "crossborder_fee_pct": 2.5,
      "crossborder_fee_min": 0.5,
      "wallet_tokenization_fee": 1,
      "wallet_deposit_fee_pct": 3,
      "wallet_deposit_fee_min": 2,
      "wallet_withdrawal_fee": 5,
      "kyc_verification_fee": 1,
      "chargeback_fee": 30,
      "prepay_discount_6m": 0,
      "prepay_discount_1y": 0
    }
  ],
  "currency": "USD"
}

Get balance

GET/balance API key required

Returns the available balance of your business account. Fees and card funding are paid from this balance.

Example request

curl "https://api.paymore.io/v1/balance" \
  -H "X-API-Key: $PAYMORE_API_KEY"

Response200

{
  "balance": 1500,
  "currency": "USD"
}

Get account

GET/account API key required

Returns the business account linked to the API key.

Example request

curl "https://api.paymore.io/v1/account" \
  -H "X-API-Key: $PAYMORE_API_KEY"

Response200

{
  "account": {
    "id": "3f1c2b7a-8d4e-4a61-9b0f-2e6d8c5a1f34",
    "company_name": "Acme Ltd",
    "company_email": "[email protected]",
    "plan": "startup",
    "status": "active",
    "business_balance": 1500,
    "created_at": "2026-09-14T10:22:31.512Z"
  }
}

List transactions

GET/transactions API key required

Returns the ledger of your business account, newest first. Debits are negative amounts.

Query parameters

limitinteger

Results per page. Default 50, maximum 100.

offsetinteger

Number of results to skip. Default 0.

typestring

Filter by type: deposit, fee, card_issuance, card_funding, kyc_fee, subscription, withdrawal, refund.

Example request

curl "https://api.paymore.io/v1/transactions" \
  -H "X-API-Key: $PAYMORE_API_KEY"

Response200

{
  "transactions": [
    {
      "id": "c7a1e9d2-5b3f-4c8e-a6d1-0f2b4e8c9a71",
      "business_id": "3f1c2b7a-8d4e-4a61-9b0f-2e6d8c5a1f34",
      "type": "card_funding",
      "amount": -102,
      "description": "Card funding 9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d: $100 + $2.00 fee",
      "reference_id": null,
      "created_at": "2026-10-02T14:05:11.208Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

KYC & End Users

Submit KYC

POST/kyc/submit API key required

Creates an end user, or resubmits an existing one, for identity verification. The KYC fee of your plan is charged on every submission. Verification is reviewed by the PayMore compliance team.

Body parameters

external_user_idstringrequired

Your own unique identifier for this user.

first_namestringrequired

Legal first name.

last_namestringrequired

Legal last name.

emailstringrequired

Email address.

phonestringrequired

Phone number in international format.

countrystringrequired

Country of residence.

addressstringrequired

Residential address.

id_numberstringrequired

National ID number.

dobstring

Date of birth, YYYY-MM-DD.

passport_numberstring

Passport number.

document_typestring

passport, national_id or driving_license.

document_front_base64string

Front of the document, base64 encoded image.

document_back_base64string

Back of the document, base64 encoded image.

selfie_base64string

Selfie holding the document, base64 encoded image.

Example request

curl -X POST "https://api.paymore.io/v1/kyc/submit" \
  -H "X-API-Key: $PAYMORE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "external_user_id": "user_123", "first_name": "John", "last_name": "Doe", "email": "[email protected]", "phone": "+971501234567", "country": "AE", "address": "Downtown, Dubai", "id_number": "784-1990-1234567-1", "dob": "1990-01-15", "document_type": "passport", "document_front_base64": "iVBORw0KGgo..." }'

Response201

{
  "success": true,
  "end_user_id": "550e8400-e29b-41d4-a716-446655440000",
  "external_user_id": "user_123",
  "kyc_status": "pending"
}

If the same ID or passport number already exists under your account, the response also contains "has_duplicate_warnings": true.

Get KYC status

GET/kyc/{external_user_id} API key required

Returns the verification status of an end user. kyc_status is one of none, pending, approved, rejected.

Example request

curl "https://api.paymore.io/v1/kyc/user_123" \
  -H "X-API-Key: $PAYMORE_API_KEY"

Response200

{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "external_user_id": "user_123",
    "first_name": "John",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+971501234567",
    "kyc_status": "approved",
    "kyc_submitted_at": "2026-10-01T09:12:44.103Z",
    "kyc_reviewed_at": "2026-10-01T15:30:02.871Z"
  }
}

List end users

GET/end-users API key required

Returns all end users submitted under your account, newest first.

Query parameters

limitinteger

Results per page. Default 50, maximum 100.

offsetinteger

Number of results to skip. Default 0.

kyc_statusstring

Filter by none, pending, approved or rejected.

Example request

curl "https://api.paymore.io/v1/end-users" \
  -H "X-API-Key: $PAYMORE_API_KEY"

Response200

{
  "end_users": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "external_user_id": "user_123",
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "phone": "+971501234567",
      "kyc_status": "approved",
      "kyc_submitted_at": "2026-10-01T09:12:44.103Z",
      "kyc_reviewed_at": "2026-10-01T15:30:02.871Z",
      "created_at": "2026-10-01T09:12:44.103Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

Cards

Request a card

POST/cards/issue API key required

Requests a new card for an end user whose KYC is approved. The card issuance fee of your plan is charged immediately. The request starts as pending and becomes active once provisioned by PayMore; poll GET /cards/{card_id} for its status.

Body parameters

external_user_idstringrequired

End user who will own the card.

card_type_idstring

Card product to issue. Omit for the default product.

Example request

curl -X POST "https://api.paymore.io/v1/cards/issue" \
  -H "X-API-Key: $PAYMORE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "external_user_id": "user_123" }'

Response201

{
  "success": true,
  "card_request_id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
  "status": "pending",
  "message": "Card request submitted. Our admin team will activate it and fill in card details. Check status via GET /cards/{card_id}."
}

List cards

GET/cards API key required

Returns all cards under your account, newest first. Card status is one of pending, reviewing, active, frozen, rejected, cancelled, disabled.

Query parameters

limitinteger

Results per page. Default 50, maximum 100.

offsetinteger

Number of results to skip. Default 0.

statusstring

Filter by card status.

Example request

curl "https://api.paymore.io/v1/cards" \
  -H "X-API-Key: $PAYMORE_API_KEY"

Response200

{
  "cards": [
    {
      "id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
      "end_user_id": "550e8400-e29b-41d4-a716-446655440000",
      "card_type_id": null,
      "status": "active",
      "card_balance": 100,
      "daily_limit": null,
      "created_at": "2026-10-02T11:00:00.000Z",
      "updated_at": "2026-10-02T14:05:11.208Z",
      "end_user": {
        "external_user_id": "user_123",
        "first_name": "John",
        "last_name": "Doe"
      }
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

Get card

GET/cards/{card_id} API key required

Returns a single card. Card number, expiry and CVV are included only while the card is active.

Example request

curl "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d" \
  -H "X-API-Key: $PAYMORE_API_KEY"

Response200

{
  "card": {
    "id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
    "end_user_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "active",
    "card_balance": 100,
    "daily_limit": null,
    "created_at": "2026-10-02T11:00:00.000Z",
    "updated_at": "2026-10-02T14:05:11.208Z",
    "end_user": {
      "external_user_id": "user_123",
      "first_name": "John",
      "last_name": "Doe"
    },
    "card_number": "4111 1111 1111 1111",
    "card_expiry": "10/29",
    "card_cvv": "123"
  }
}

Fund card

POST/cards/{card_id}/fund API key required

Loads funds onto an active card. The amount plus the funding fee of your plan is deducted from your business balance. Maximum $10,000 per request.

Body parameters

amountnumberrequired

Amount in USD to load onto the card.

Example request

curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/fund" \
  -H "X-API-Key: $PAYMORE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 100 }'

Response200

{
  "success": true,
  "funded_amount": 100,
  "fee": 2,
  "new_card_balance": 100
}

Unload card

POST/cards/{card_id}/unload API key required

Moves funds from an active card back to your business balance. No fee is charged.

Body parameters

amountnumberrequired

Amount in USD to withdraw from the card.

Example request

curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/unload" \
  -H "X-API-Key: $PAYMORE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 50 }'

Response200

{
  "success": true,
  "unloaded_amount": 50,
  "new_card_balance": 50
}

Freeze card

POST/cards/{card_id}/freeze API key required

Temporarily blocks an active card. A frozen card cannot be funded or unloaded until it is unfrozen.

Example request

curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/freeze" \
  -H "X-API-Key: $PAYMORE_API_KEY" \
  -H "Content-Type: application/json"

Response200

{
  "success": true,
  "card_id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
  "status": "frozen"
}

Unfreeze card

POST/cards/{card_id}/unfreeze API key required

Reactivates a frozen card.

Example request

curl -X POST "https://api.paymore.io/v1/cards/9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d/unfreeze" \
  -H "X-API-Key: $PAYMORE_API_KEY" \
  -H "Content-Type: application/json"

Response200

{
  "success": true,
  "card_id": "9b2f6c1e-4a7d-4e2b-8c3f-1d5e7a9b0c2d",
  "status": "active"
}

International Transfers

Not yet available via API

Cross-border transfers are currently available in the PayMore app only. API endpoints will be published here when released.

Errors

Errors use standard HTTP status codes and always return a JSON body with an error message. Some errors include extra fields, such as required on 402.

{
  "error": "Insufficient business balance",
  "required": 102,
  "funding_amount": 100,
  "fee": 2
}
400

Invalid request: missing fields, invalid JSON or invalid amount.

"Missing required fields: country, id_number"
401

API key missing, invalid or revoked.

"Invalid API key"
402

Business balance too low to cover the amount or fee.

"Insufficient business balance"
403

Business account not active, KYC not approved, or card not active.

"KYC status is 'pending'. Must be 'approved' before issuing cards."
404

Endpoint, end user or card not found.

"Card not found"
409

Card is not in the right state for this action.

"Card status is 'active'. Only 'frozen' cards can be unfrozen."
429

Rate limit exceeded. Wait 60 seconds (see the Retry-After header).

"Rate limit exceeded. Retry after 60 seconds."
500

Unexpected server error. Safe to retry read requests.

"Internal server error"