Plaidly Docs

API Reference

Complete REST API reference for Plaidly, generated from the OpenAPI 3.1 specification

API Reference

The Plaidly API is documented via an OpenAPI 3.1 specification (openapi: "3.1.0", info.version: "1.0").

Spec download: GET https://api.plaidly.io/openapi.json currently requires the same auth as merchant endpoints (verified live 2026-07-11 — an unauthenticated request returns 401 with {"code":7,"message":"missing or invalid authorization header"}). Register a sandbox merchant first (see Register a merchant) and pass its api_key, or use the copy checked into plaidly-api/api/openapi.yaml.

curl https://api.plaidly.io/openapi.json \
  -H "X-API-Key: your_api_key" \
  -o plaidly-openapi.json

You can import the resulting file directly into Postman, Insomnia, or any OpenAPI-compatible tool. Or browse the source directly: api/openapi.yaml.

Base URL

https://api.plaidly.io

All endpoints are versioned under /v1. See Versioning & deprecation policy for what that guarantees.

Authentication

Public read endpoints need no auth. Merchant-scoped endpoints use X-API-Key.

Endpoints

Payment sessions

MethodPathDescription
POST/v1/payment_sessionsCreate a merchant payment session
POST/v1/payment_sessions/demoCreate a public demo session
GET/v1/payment_sessions/{session_id}Retrieve a payment session
POST/v1/payment_sessions/{session_id}/simulateMark a sandbox/demo session complete without a real transaction
POST/v1/payment_sessions/{session_id}/webhook/retryManually redeliver the webhook for a session
GET/v1/payment_sessions/{session_id}/receiptDownload the PDF receipt

Merchants

MethodPathDescription
POST/v1/merchantsRegister a new merchant (public for sandbox)
GET/v1/meGet the current merchant profile
POST/v1/me/credentials/rotateRotate the API key or webhook secret
POST/v1/me/credentials/revokeRevoke the previous credential from the latest rotation

Discovery

MethodPathDescription
GET/v1/payment_methodsList globally enabled payment rails (chain/network/token)
GET/v1/ratesFetch spot rates for supported assets
GET/v1/sandbox/faucetsList testnet faucet URLs

Operations

MethodPathDescription
POST/v1/payoutsRequest a payout
GET/v1/payouts/{payout_id}Retrieve a payout
POST/v1/walletsCreate a wallet
GET/v1/walletsList wallets
GET/v1/wallets/{wallet_id}Retrieve a wallet
GET/v1/wallets/{wallet_id}/transactionsList wallet transactions
POST/v1/agent-wallets/{agent_wallet_id}/spend-attemptsEvaluate/record an agent wallet outbound spend attempt

Catalog

MethodPathDescription
POST/v1/storesCreate a store
GET/v1/storesList the authenticated merchant's stores
GET/v1/stores/{store_id}Get a store
PATCH/v1/stores/{store_id}Update a store in place
DELETE/v1/stores/{store_id}Hard-delete a draft, never-published store
POST/v1/stores/{store_id}/publishPublish a store
POST/v1/stores/{store_id}/archiveArchive a store
POST/v1/productsCreate a product
GET/v1/productsList the authenticated merchant's products
GET/v1/products/{product_id}Get a product
PATCH/v1/products/{product_id}Update in place (draft) or create a new version (published)
DELETE/v1/products/{product_id}Hard-delete a draft, never-published product
POST/v1/products/{product_id}/publishPublish a product
POST/v1/products/{product_id}/archiveArchive a product
POST/v1/plansCreate a plan
GET/v1/plansList the authenticated merchant's plans
GET/v1/plans/{plan_id}Get a plan
PATCH/v1/plans/{plan_id}Update in place (draft) or create a new version (published)
DELETE/v1/plans/{plan_id}Hard-delete a draft, never-published plan
POST/v1/plans/{plan_id}/publishPublish a plan
POST/v1/plans/{plan_id}/archiveArchive a plan
POST/v1/pricesCreate a price
GET/v1/pricesList the authenticated merchant's prices
GET/v1/prices/{price_id}Get a price
PATCH/v1/prices/{price_id}Update in place (draft) or create a new version (published)
DELETE/v1/prices/{price_id}Hard-delete a draft, never-published price
POST/v1/prices/{price_id}/publishPublish a price
POST/v1/prices/{price_id}/archiveArchive a price
GET/v1/catalog/productsPublic buyer-agent discovery listing of published products (no auth)
GET/v1/catalog/products/{product_id}Public buyer-agent discovery detail for one published product (no auth)
POST/v1/catalog/prices/{price_id}/checkout-intentResolve a published price into checkout fields (no auth)

There is no distinct entitlement resource or endpoint — entitlement is a freeform metadata object field on plan. Full walkthrough: Create a store, product, and price and Create or select a checkout.

Request format

All request bodies use application/json:

curl -X POST https://api.plaidly.io/v1/payment_sessions \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10.0,
    "expires_in": "15m",
    "paymentMethod": {
      "methodID": 0,
      "chain": "solana",
      "token": "USDC",
      "network": "mainnet"
    },
    "metadata": { "order_id": "ord_123" }
  }'

Response format

Most responses are application/json. Successful responses include the resource object directly (no {"session": {...}} wrapper):

{
  "session_id": "sess_test_01HX...",
  "merchant_id": "mer_01HX...",
  "expected_amount": 10,
  "received_amount": 0,
  "address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV",
  "status": "pending",
  "demo": false,
  "paymentMethod": {
    "methodID": 0,
    "chain": "solana",
    "token": "USDC",
    "network": "mainnet"
  }
}

Error format

{
  "code": 5,
  "message": "idempotency key was already used with a different payload"
}

code is a small integer enum today (not a string slug like "session_not_found") — see the full code table and the richer envelope the platform is converging on in Error model.

Status codes

CodeMeaning
200Success
201Created
400Bad request — check your request body (code: 3)
401 / 403Auth failure — invalid, missing, or insufficient credentials (code: 7)
404Not found (code: 2)
409Conflict — duplicate idempotency key with a different payload (code: 5)
429Rate limited (code: 4)
500Internal server error (code: 1)

Rate limits

Each merchant gets a default limit of 60 requests per minute, set on the Merchant object as rate_limit_per_minute (visible via GET /v1/me) — it is per-merchant, not a single global constant, and can differ from the default. Exceeding it returns 429.

There are currently no X-RateLimit-* response headers — you cannot introspect remaining quota from response headers today; track your own request rate against the rate_limit_per_minute value from GET /v1/me instead.

Idempotency

POST requests to a subset of endpoints support idempotency via the Idempotency-Key header. See Idempotency for exactly which endpoints support it today.

On this page