API Quickstart · USD 59
Payments API: quickstart
Create your first charge in about ten minutes. Covers authentication, one successful request, the response you should expect and the four errors new integrators hit.
Written against v2.4.0 of the API, from the OpenAPI schema, the handler code and the release notes you supplied. Every request below was run against your sandbox and the responses are the ones it returned.
Document control
- Document number
- DOC-API-QS-02
- Version
- 2.1
- Effective
- 2 October 2026
- Owner
- Developer Experience
- Approved by
- API Platform Lead
- Next review
- 2 January 2027
- Classification
- Public
Map
Where this page sits
This is the first page of the developer documentation set. It assumes nothing except that the reader has a sandbox account and a terminal.
| Page | Answers | Status |
|---|---|---|
| Quickstart | How do I make one successful call? | This document |
| Authentication | Key types, rotation, scopes | Published |
| Charges reference | Every field on the charge object | Published |
| Webhooks | Event types and signature verification | Draft, see clause 7 |
| Migration from v1 | What changed and what broke | Published |
| Errors | Full code list | Published |
Setup
Before your first request
- A sandbox secret key from the dashboard, beginning sk_test_
- TLS 1.2 or later. The API refuses plaintext and does not redirect
- An idempotency key generator, any UUID v4 source
- Your account in test mode. Live keys will not work against the sandbox host
Request
Create a charge
Amounts are integers in the smallest currency unit. The example below charges USD 24.50.
Request
curl https://api.sandbox.tilburypay.com/v2/charges \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-H "Idempotency-Key: 8f14e45f-ea4c-4f2a-9b1e-2c9d0e7a1b33" \
-d amount=2450 \
-d currency=usd \
-d source=tok_visa \
-d description="Order 10241" Response
What comes back
201 Created
{
"id": "ch_3Pk2LqB7xQ1a",
"object": "charge",
"amount": 2450,
"amount_captured": 2450,
"currency": "usd",
"status": "succeeded",
"captured": true,
"created": 1791878400,
"description": "Order 10241",
"livemode": false,
"payment_method_details": {
"type": "card",
"card": { "brand": "visa", "last4": "4242", "country": "US" }
},
"receipt_url": "https://sandbox.tilburypay.com/receipts/ch_3Pk2LqB7xQ1a"
} Reference
Request parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
| amount | integer | Yes | Smallest currency unit. 2450 is USD 24.50. Minimum 50 |
| currency | string | Yes | Three letter ISO code, lowercase |
| source | string | Yes | A token or a stored payment method id |
| description | string | No | Up to 350 characters. Appears on the customer statement where the network allows |
| capture | boolean | No | Defaults true. False authorises only, and you must capture within 7 days |
| metadata | object | No | Up to 20 keys, 500 characters per value. Never put card data here |
| receipt_email | string | No | Sends a receipt in test mode too. Be careful with real addresses |
Idempotency-Key is a header, not a parameter. It is optional in the schema and required in practice: without it a network retry creates a second charge.
Errors
The four you will hit first
| Code | HTTP | Cause | Fix |
|---|---|---|---|
| amount_too_small | 400 | Amount below the 50 minimum for the currency | Validate before sending. The minimum differs by currency |
| resource_missing | 404 | Token already used, or created with a different key | Tokens are single use. Create one per charge |
| idempotency_key_in_use | 409 | Same key, different request body, within 24 hours | Reuse the key only for a genuine retry of the same request |
| rate_limit | 429 | More than 100 requests per second | Back off exponentially. Read the Retry-After header |
Error shape
{
"error": {
"type": "invalid_request_error",
"code": "amount_too_small",
"message": "Amount must be at least 50 usd.",
"param": "amount",
"doc_url": "https://docs.tilburypay.com/errors/amount_too_small"
}
} Read error.code, never error.message. The message wording changes without notice; the code is stable and is covered by the deprecation policy.
Open
Questions left for your engineers
Four things could not be documented from the code and the schema alone. They are marked in the draft and must be answered before this page goes to the public portal.
| Question | Why it matters | Who answers |
|---|---|---|
| Is the 100 per second rate limit per key or per account? | The handler reads an account field but the gateway config suggests per key | API Platform |
| Does the 7 day capture window count calendar or working days? | The constant is 604800 seconds, so calendar, but the help centre says working | API Platform |
| Is metadata returned on the v1 compatibility endpoint? | Migration readers will assume yes and it is not in the v1 serialiser | Platform |
| Webhook signature: which version header ships in v2.4? | Blocks the webhooks page, which is why it is still draft | Platform |
Document control
Revision history
| Version | Date | Author | Change |
|---|---|---|---|
| 2.1 | 1 October 2026 | DocRail | Idempotency header promoted from a footnote to clause 5 after three support tickets about duplicate charges. |
| 2.0 | 24 September 2026 | DocRail | Rewritten for v2.4.0. Response example re-run against sandbox, receipt_url field added, capture default documented. |
| 1.3 | 12 August 2026 | DocRail | Error table cut from eleven codes to the four that account for most first week failures. |
| 1.0 | 30 July 2026 | DocRail | First issue, written against v2.1.0. |