GoWire.ai API
A JSON REST API over HTTPS. Amounts are integers in the currency's minor unit unless the field says otherwise, timestamps are RFC 3339 in UTC, and every write accepts an idempotency key so retries are safe.
Authentication
Send your secret key as a bearer token on every request. Keys are scoped to one environment and one entity; sk_test_ keys never move money. Rotate from the dashboard — the previous key stays valid for one hour.
Authorization: Bearer sk_live_9f2c8a41d7
Idempotency-Key: 8a41-inv-20268
Content-Type: application/json
Errors and rate limits
Errors carry a stable code, a human message, and field where a specific input is at fault. Rate limits are 100 requests per second per key, returned in X-RateLimit-Remaining.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A field is missing or malformed; field names the offender. |
| 401 | unauthenticated | Key missing, revoked, or from the wrong environment. |
| 402 | insufficient_funds | Balance will not cover the amount plus the fee. |
| 409 | idempotency_conflict | Key reused with a different body. |
| 422 | corridor_unavailable | Valid request, but that pair is not open right now. |
| 429 | rate_limited | Back off; Retry-After gives the wait in seconds. |
Retrieve a quote
Price a corridor before committing. A quote is free, valid for 30 minutes, and its id can be passed to payment creation to guarantee the rate you showed the user.
| source_currency string · required | ISO 4217 code of the currency you are sending. |
| target_currency string · required | ISO 4217 code the beneficiary receives. |
| amount integer · required | Minor units. Send with source_side to state which leg is fixed. |
| source_side boolean | True (default) fixes the send amount; false fixes the receive amount. |
curl -G https://api.gowire.ai/v1/quotes \
-H "Authorization: Bearer sk_live_9f2c" \
-d source_currency=EUR \
-d target_currency=USD \
-d amount=5000000
200 OK
{
"id": "quo_71bd44",
"rate": 1.0842,
"source": { "currency": "EUR", "amount": 5000000 },
"target": { "currency": "USD", "amount": 5402085 },
"fee": { "currency": "EUR", "amount": 17500 },
"eta": "2026-08-27T14:22:00Z",
"expires_at": "2026-08-27T14:11:36Z"
}
Create a payment
Creates and routes a payment. Always send an Idempotency-Key: repeating the same key returns the original payment rather than sending twice. The response is immediate; settlement arrives by webhook.
| quote string | Quote id to honour. Omit to price at the current rate. |
| source object · required | currency and amount in minor units. |
| target object · required | currency, and amount when fixing the receive leg. |
| beneficiary string · required | Stored beneficiary id, or an inline object of account details. |
| reference string | Shown to the beneficiary and used for reconciliation matching. |
| metadata object | Up to 40 key-value pairs returned on every event. |
POST /v1/payments
Idempotency-Key: 8a41-inv-20268
{
"quote": "quo_71bd44",
"source": { "currency": "EUR", "amount": 5000000 },
"target": { "currency": "USD" },
"beneficiary": "ben_8f2c19",
"reference": "INV-20268",
"metadata": { "invoice_id": "20268" }
}
201 Created
{
"id": "pay_3ka91x",
"status": "routing",
"rate": 1.0842,
"source": { "currency": "EUR", "amount": 5000000 },
"target": { "currency": "USD", "amount": 5402085 },
"fee": { "currency": "EUR", "amount": 17500 },
"rail": "fedwire",
"eta": "2026-08-27T14:22:00Z",
"created_at": "2026-08-27T13:41:36Z"
}
Retrieve a payment
Returns the current state and the full timeline of a payment, including each rail decision and screening outcome. Safe to poll, though webhooks are cheaper.
| id string · required | The payment id, or your idempotency key prefixed with idk_. |
| expand array | timeline, beneficiary, or evidence to inline related objects. |
200 OK
{
"id": "pay_3ka91x",
"status": "credited",
"timeline": [
{ "state": "screening", "at": "2026-08-27T13:41:38Z" },
{ "state": "routing", "at": "2026-08-27T13:41:52Z" },
{ "state": "sent", "at": "2026-08-27T13:42:10Z" },
{ "state": "credited", "at": "2026-08-27T14:03:41Z" }
],
"evidence": "evd_5c81a0"
}
Submit a batch
Up to 5,000 payments in one call. Validation runs before anything moves; valid rows send and invalid rows wait with an itemised reason. Poll the batch or listen for batch.validated.
| payments array · required | Payment objects, identical in shape to a single create. |
| on_invalid enum | send_valid (default) or reject_all. |
| approval enum | auto, or require_dual to hold for a second approver. |
202 Accepted
{
"id": "bat_9d20fe",
"status": "validating",
"count": 4812,
"valid": null,
"invalid": null,
"created_at": "2026-08-27T13:44:02Z"
}
List balances
One entry per currency you hold, with available and reserved amounts. Reserved covers payments created but not yet settled.
| currency string | Filter to a single ISO 4217 code. |
| include_zero boolean | Include currencies with no balance. Default false. |
200 OK
{
"data": [
{ "currency": "EUR", "available": 18240055, "reserved": 5000000 },
{ "currency": "USD", "available": 9930412, "reserved": 0 },
{ "currency": "SGD", "available": 2145000, "reserved": 0 }
]
}
Create a beneficiary
Stores a payee with validated account details. Validation is corridor-specific: IBAN check digits in Europe, routing number and account type in the US, and so on.
| name string · required | Legal name as held by the beneficiary bank. |
| currency string · required | Currency this account can receive. |
| account object · required | Corridor-specific fields: iban, routing_number, bsb, clabe. |
| type enum | business or individual. Affects screening. |
201 Created
{
"id": "ben_8f2c19",
"name": "Kesler Manufacturing GmbH",
"currency": "EUR",
"account": { "iban": "DE89•••••••••3000" },
"type": "business",
"verified": true
}
Webhooks
Events are signed with HMAC-SHA256 over the raw body in Gowire-Signature, retried with exponential backoff for 24 hours, and replayable from the dashboard. Verify the signature before trusting the payload.
Rail selected; the payment is on its way out.
Beneficiary bank confirmed the credit.
Screening needs a decision from you.
Rejected, with the reason and a retry option.
Pre-flight finished; valid and invalid rows listed.
A settlement the agent could not match alone.
Changelog
Breaking changes ship behind a new dated version and never to v1. We support each version for 24 months after its successor.