Sample API Documentation

Payments API (v1)

This is a realistic API documentation sample for a payment-processing service. It demonstrates authentication, idempotency, pagination, request/response examples, and an error model.

Base URL

https://api.acmepayments.example/v1

Authentication

Authenticate using an API key sent in the Authorization header.

Authorization: Bearer <API_KEY>

Keep keys server-side. If a key is leaked, rotate it immediately.

Idempotency

For requests that create or modify resources (for example, POST /payments), send an idempotency key to prevent accidental duplicate charges if a client retries.

Idempotency-Key: 2a9f9f03-18c4-4e2a-a4b7-3a91b1b7d8c1

The server stores the first successful response for that key for 24 hours. Retries return the same response.

Common Headers

Content-Type: application/json
Accept: application/json
Authorization: Bearer <API_KEY>
Idempotency-Key: <UUID> (recommended for POST/PATCH)

Resource Model

Payment

  • id (string): Payment identifier, for example pay_3Xn9...
  • amount (integer): Amount in minor units (cents), for example 1999
  • currency (string): ISO 4217 currency code, for example USD
  • status (string): requires_confirmation | succeeded | failed | refunded
  • customer_id (string): Customer identifier
  • created_at (string): RFC 3339 timestamp
  • metadata (object): Optional key/value data (max 20 keys)

Endpoints

1) Create a payment

POST /payments

Request body

{
 "amount": 1999,
 "currency": "USD",
 "customer_id": "cus_8F3k1",
 "payment_method": {
 "type": "card",
 "card_token": "tok_visa_123"
 },
 "confirm": true,
 "metadata": {
 "order_id": "A-100045"
 }
}

Notes

  • amount is in minor units (cents for USD).
  • confirm=true attempts to capture immediately. If omitted, the payment is created in requires_confirmation.

Response: 201 Created

{
 "id": "pay_3Xn9Qv0c",
 "amount": 1999,
 "currency": "USD",
 "status": "succeeded",
 "customer_id": "cus_8F3k1",
 "created_at": "2026-01-10T12:00:00Z",
 "metadata": {
 "order_id": "A-100045"
 }
}

2) Retrieve a payment

GET /payments/{payment_id}

GET /payments/pay_3Xn9Qv0c

Response: 200 OK

{
 "id": "pay_3Xn9Qv0c",
 "amount": 1999,
 "currency": "USD",
 "status": "succeeded",
 "customer_id": "cus_8F3k1",
 "created_at": "2026-01-10T12:00:00Z",
 "metadata": {
 "order_id": "A-100045"
 }
}

3) List payments (pagination)

GET /payments?limit=20&starting_after=pay_...

Parameters

  • limit (integer, 1–100): Number of results to return (default 20)
  • starting_after (string): Cursor for pagination (exclusive)
  • customer_id (string): Optional filter

Response: 200 OK

{
 "data": [
 {
 "id": "pay_3Xn9Qv0c",
 "amount": 1999,
 "currency": "USD",
 "status": "succeeded",
 "customer_id": "cus_8F3k1",
 "created_at": "2026-01-10T12:00:00Z",
 "metadata": {"order_id": "A-100045"}
 }
 ],
 "has_more": false,
 "next_cursor": null
}

4) Refund a payment

POST /payments/{payment_id}/refunds

Request body

{
 "amount": 1999,
 "reason": "requested_by_customer"
}

Response: 201 Created

{
 "refund_id": "ref_72Kp1",
 "payment_id": "pay_3Xn9Qv0c",
 "amount": 1999,
 "currency": "USD",
 "status": "succeeded",
 "created_at": "2026-01-10T12:05:00Z"
}

Error Handling

Errors return JSON with a stable shape. Use error.code for programmatic handling and show error.message to users only after sanitization.

Error object

{
 "error": {
 "type": "invalid_request",
 "code": "amount_too_small",
 "message": "Amount must be at least 50 cents.",
 "param": "amount",
 "request_id": "req_9n2Z1"
 }
}

Common HTTP status codes

  • 400 Invalid request (missing fields, bad types)
  • 401 Authentication failed (missing/invalid API key)
  • 403 Not permitted (key lacks scope)
  • 404 Resource not found
  • 409 Conflict / idempotency mismatch
  • 429 Rate limited
  • 500 Server error

Rate limiting

The API enforces rate limits per key. When limited, responses include:

429 Too Many Requests
Retry-After: 2

Best Practices

  • Always send Idempotency-Key for create/modify requests.
  • Log request_id to correlate client-side errors with server logs/support.
  • Validate currencies and minor-unit amounts on the client.
  • Version your integrations by pinning to /v1 and monitoring changelogs.

This is a sample article to demonstrate how I write.