Home
Home
  1. Home
  • Welcome
    • About Ontime
    • Overview
    • Test and Learn Projects
  • Authentication
  • Idempotency
  • Availability Check
    • Light Availability Check
      POST
    • Full Availability Check
      POST
  • Payment Management
    • Mandates
      • Create a new mandate
      • Cancel an existing mandate
      • Get a Mandate
      • Get many Mandates
    • Payment Requests
      • Instruct a new payment request
      • Cancel an existing payment request
      • Get a Payment
      • Get many Payments
  • Payouts
    • Get a Payout
      GET
    • Get Available Payouts
      GET
  • Webhooks
    • Mandate Created/Updated
    • Payment Request Created/Updated
    • Payout Created
  • Schemas
    • Schemas
      • PaymentManagement
        • MandateLimitations
        • MandateRecordResponse
        • MandateDeleteResponse
        • GetMandatesPagedResponse
        • MandateStatus
        • MandateRecordRequest
        • PaymentCreateRequest
        • PaymentResponse
        • PaymentDeleteResponse
        • GetPaymentsPagedResponse
        • PaymentStatus
        • AuthorisationSource
      • Payout
        • PayoutResponse
        • PayoutPaymentRequestItem
        • ListPayoutsResponse
      • Deprecated
        • Invitation
        • Consumer
        • PaymentMethod
        • ProductPaymentStatus
        • ProductStatus
        • PaymentRequestData
      • Webhook
        • Webhook
        • WebhookPaymentRequestPayload
        • WebhookMandatePayload
        • WebhookPayoutPayload
      • Core
        • ConsumerData
        • ProblemDetails
        • Metadata
        • PagingResponse
      • Availability
        • FullAvailabilityCheckRequest
        • FullAvailabilityCheckResponse
        • AvailabilityStatus
        • LightAvailabilityCheckRequest
        • LightAvailabilityCheckResponse
Home
Home
  1. Home

Idempotency

Idempotency keys (payments)#

When you call an API over the internet, retries happen—because of timeouts, transient network issues, or a response being lost after the server has already processed the request. For mutating operations (like POST), retries can accidentally perform the same action more than once.
To make retries safe, the Payments API supports idempotency keys via the Idempotency-Key header.

What is idempotency?#

A request is idempotent if performing it multiple times has the same effect as performing it once.
GET requests should be idempotent by nature (they should not change server state).
POST requests are often not idempotent by default (re-sending can create duplicates).
An idempotency key makes a mutating request behave as-if idempotent from the client’s perspective.

How idempotency works in this API#

Send an Idempotency-Key header with supported mutating endpoints:
Idempotency-Key: <uuid>
When you provide an idempotency key:
1.
First request with a new key
We execute the operation.
We store the response for that key.
We return the response.
2.
Subsequent requests with the same key (within 24 hours)
We do not execute the operation again.
We return the previously stored response.
This gives you “exactly-once” behaviour at the API boundary for the same request keyed by Idempotency-Key (within the retention window).

Retention window (24 hours)#

Idempotency keys are retained for 24 hours.
If you retry within 24 hours using the same key, you’ll receive the original response.
If you reuse a key after 24 hours, it may no longer be recognised and the request may execute again (which may cause mutating side effects).
Only reuse the same key when retrying the same logical operation. Reusing a key for a different operation within 24 hours can cause you to receive a stored response that does not match your new request.

Generating an idempotency key#

Use a random UUID (recommended).
Examples:
7d2b3f0c-8e66-4d9c-9a2c-4f6e3b2f5b21
d7f59c3a-13c2-4f2f-8d3d-0d1a2f9a3b7c
Common generation options:
.NET: Guid.NewGuid()
Java: UUID.randomUUID()
JavaScript: crypto.randomUUID()
Python: uuid.uuid4()
Do not embed secrets or personal data in the key (keys may be logged for traceability).

Example: Instruct a new payment request#

Endpoint
POST https://api.payments.ontime.co/payments
OperationId: create_new_payment_request
This endpoint creates a new payment request. Ontime will attempt to satisfy the payment request following the next available employee pay date. Payments are not automatically re-occurring.

Authentication#

This endpoint requires:
API key header: x-api-key: …
OAuth 2.0 token header: Authorization: Bearer …
Scope: payments:write (Create and cancel payment requests)

Request (with Idempotency-Key)#

Field notes (from the endpoint schema)#

payment_record (required): request body root object
mandate_id (required, UUID): the unique identifier for the active mandate this payment request is linked to
amount (required, integer): in the smallest denomination (e.g. 455 = £4.55 in pounds/pence)
due_date (optional, date or null): a future date on which the payment is due
currency (optional, ISO 4217 or null): defaults to GBP if not provided
metadata (optional): freeform, biller-provided metadata; limited to 3 items of 1 MB each
allow_post_due_date_deduction (optional, boolean; default false):
If true, we will make the deduction from the consumer even if the expected pay date is after your selected due date.
If false, we will reject the payment request if the expected pay date is after your selected due date.

What happens on retry?#

If your client does not receive a response (timeout, connection drop, etc.), retry the request with the same Idempotency-Key.
Key not used before (within 24 hours): we execute the request and return the result.
Key already used (within 24 hours): we return the previous result and do not execute again.
To get the expected behaviour, retries should use the same:
HTTP method (POST)
path (/payments)
payload (the same payment_record)

Client retry best practices#

Generate one idempotency key per logical operation, and reuse it only for retries of that operation.
Persist the key until you receive a definitive success/failure response (important for mobile or background jobs).
Retry only on transient failures (timeouts, connection errors, 5xx responses).
Use exponential backoff + jitter to avoid retry storms.

Summary#

Send Idempotency-Key with payment creation requests you may need to retry.
Within 24 hours, the same key will return the original response and prevent duplicate execution.
After 24 hours, reusing a key may execute the request again and cause mutating side effects.
Previous
Authentication
Next
Availability Check