Authorize, capture, reverse, and increment card transactions. Token-only — you never send a raw PAN.
panToken. The token comes from your terminal SDK (chip / swipe / tap) or your tokenization service — never from a user typing card digits. The PAN itself never traverses api.rmous.org, which keeps your integration out of PCI-DSS scope.
A new authorization moves through one of these paths:
POST /v1/authorizations ↓ [Authorization Approved] — hold on the card, funds reserved ↓ POST /capture [Authorization Partial] — some captured, more remaining ↓ POST /capture (remainder) [Authorization Charged] — terminal, fully captured ↓ POST /reverse [Authorization Reversed] — terminal, refunded OR POST /v1/authorizations ↓ [Authorization Declined] — terminal, audit-only
Submit a new card authorization. The pipeline: resolve panToken → card status gate → expiration gate → limit-engine evaluation → idempotency replay check → INSERT Issuing.Authorizations → fire authorization.approved or .declined webhook.
| Field | Type | Description |
|---|---|---|
| panToken required | string(17) | Opaque card token from your terminal SDK or tokenization service. |
| amount required | number | Positive number. USD by default. |
| currency optional | string | Core.Currencies.RecordId. Defaults to USD. |
| channel optional | string | Issuing.Channels.RecordId: POS, ECOMM, etc. |
| mcc optional | string(4) | 4-digit merchant-category code. |
| merchant optional | string | Merchant.Accounts.RecordId. |
| merchantNameRaw optional | string | Up to 64 chars. What appears on the cardholder’s statement. |
| avsResult optional | enum | Y / N / A / Z / U |
| cvvResult optional | enum | M / N / P / U / X |
| mode optional | enum | 01 card-present · 02 CNP · 03 recurring · 04 token · 05 MOTO |
| metadata optional | object | JSON passthrough — opaque to RMO, returned as-is on read. |
curl https://api.rmous.org/v1/authorizations \ -H "X-API-Key: pk_test_publicsandbox_2026" \ -H "Authorization: Bearer sk_test_publicsandbox_2026_anyone_can_use_this" \ -H "Idempotency-Key: order-7421" \ -H "Content-Type: application/json" \ -d '{ "panToken": "TOKEN_FROM_TERMINAL", "amount": 42.50, "channel": "POS", "mcc": "5812", "merchantNameRaw": "RMO Coffee Shop", "mode": "01" }'
{
"authorizationId": "7421589", // 7-digit human ID
"recordId": "A1b2C3d4E5f6G7h8I", // 17-char system ID
"status": "approved",
"amount": 42.50,
"approvalCode": "A7B2C3", // 6-digit
"expires": "2026-05-21T16:53:05Z" // hold expiry, 7d default
}
{
"authorizationId": "7421590",
"recordId": "D1e2C3l4I5n6E7d8X",
"status": "declined",
"amount": 42.50,
"reasonCode": "61",
"reasonMessage": "Daily spend cap exceeded",
"details": { "limits": [ // limit-engine breach detail ] }
}
A declined response is still a successful HTTP request (200) — the network reached a decision. reasonCode follows ISO-8583 conventions; see Errors.
Convert an approved hold into a posted charge. Omitting amount captures the full remaining hold. Partial captures are allowed — the auth stays open at Authorization Partial until the remainder is captured or reversed.
| Field | Type | Description |
|---|---|---|
| amount optional | number | Partial capture amount. Must be ≤ remaining. Defaults to full remainder. |
curl https://api.rmous.org/v1/authorizations/7421589/capture \ -H "X-API-Key: $RMO_API_KEY" \ -H "Authorization: Bearer $RMO_BEARER" \ -H "Idempotency-Key: capture-7421589-1" \ -H "Content-Type: application/json" \ -d '{"amount": 30.00}' # Response (200): { "authorizationId": "7421589", "status": "partial", // or "charged" when fully captured "amountCaptured": 30.00, "acknowledged": "2026-05-14T17:01:33Z", "settled": null // only set when status="charged" }
Fires authorization.captured webhook on success.
One endpoint covers both void (before capture) and refund (after capture). The behavior is determined by the auth’s current state.
| Field | Type | Description |
|---|---|---|
| amount optional | number | Partial reverse amount. Defaults to full remaining hold or full captured amount. |
| reason optional | string | Issuing.Reasons.Code. Defaults to RV02 (customer void). |
{
"authorizationId": "7421589",
"status": "reversed", // or "partial-reversed"
"amountReversed": 42.50,
"reasonCode": "RV02",
"settled": "2026-05-14T17:08:11Z"
}
Fires authorization.reversed webhook on success.
For hotels, gas pumps, ride-share, and other open-tab scenarios. The original auth stays open; a new Authorizations row is written with isIncremental: true and parentAuthorization pointing at the original. Limit-engine evaluates against the additional amount on the parent’s card.
| Field | Type | Description |
|---|---|---|
| amount required | number | Additional amount to hold. |
| metadata optional | object | JSON passthrough. |
{
"authorizationId": "7421593",
"recordId": "I1n2C3r4E5m6T7n8L",
"parentAuthorization": "7421589",
"status": "approved",
"amount": 15.00,
"approvalCode": "A8C4F1",
"expires": "2026-05-21T16:53:05Z"
}
Look up an authorization by either its 7-digit Id (the human ID returned as authorizationId) or its 17-character RecordId. Only the issuing tenant can see their own authorizations.
curl https://api.rmous.org/v1/authorizations/7421589 \ -H "X-API-Key: $RMO_API_KEY" \ -H "Authorization: Bearer $RMO_BEARER"