#!/usr/bin/env bash
# Exchange a secret key for a short-lived access token (300s) and a refresh
# token (3900s, single-use rotation). Never expose the secret key to a browser.
set -euo pipefail
API_BASE="${RADIUMONE_API_BASE:-https://api-sandbox.radiumone.io/gateway}"
curl -sS -X POST "$API_BASE/v1/auth/token" \
-H "Content-Type: application/json" \
-d @request.json#!/usr/bin/env python3
"""Exchange a secret key for a short-lived access token. Python 3.10+, requests."""
import json
import os
from pathlib import Path
import requests
API_BASE = os.environ.get("RADIUMONE_API_BASE", "https://api-sandbox.radiumone.io/gateway")
def create_access_token() -> dict:
body = json.loads((Path(__file__).parent / "request.json").read_text())
if os.environ.get("RADIUMONE_SECRET_KEY"):
body["api_key"] = os.environ["RADIUMONE_SECRET_KEY"]
resp = requests.post(f"{API_BASE}/v1/auth/token", json=body, timeout=30)
payload = resp.json()
if not resp.ok:
raise RuntimeError(f"auth/token failed: {payload.get('type') or payload.get('code')} ({resp.status_code})")
# Cache access_token server-side for up to expires_in seconds; use
# refresh_token to get a new pair before it lapses.
return payload
if __name__ == "__main__":
print(json.dumps(create_access_token(), indent=2))
{
"status": "ok",
"request_id": "req_a1b2c3d4e5f6",
"data": {
"access_token": "<opaque, treat as a bearer string>",
"token_type": "Bearer",
"expires_in": 300,
"refresh_token": "r1rt_EXAMPLE_TOKEN_ONLY",
"refresh_expires_in": 3900,
"merchant_id": "8f1c2e10-4b3a-4c5d-9e6f-7a8b9c0d1e2f",
"publishable_key": "r1pk_test_0123456789abcdef",
"redirect_secret": null
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"request_id": "<string>",
"code": "<string>",
"retry_allowed": true,
"errors": [
{
"pointer": "<string>",
"parameter": "<string>",
"code": "<string>",
"detail": "<string>"
}
]
}{
"detail": "Missing or invalid Bearer token.",
"status": 401,
"title": "Authentication Required",
"type": "urn:radiumone:gateway:authentication-required"
}{
"detail": "An unexpected error occurred.",
"status": 500,
"title": "Internal Server Error",
"type": "urn:radiumone:gateway:internal-server-error"
}Get an access token - Payments API
Exchange your API key for a short-lived access token, plus a refresh token for secret keys, to authenticate Payments API requests.
#!/usr/bin/env bash
# Exchange a secret key for a short-lived access token (300s) and a refresh
# token (3900s, single-use rotation). Never expose the secret key to a browser.
set -euo pipefail
API_BASE="${RADIUMONE_API_BASE:-https://api-sandbox.radiumone.io/gateway}"
curl -sS -X POST "$API_BASE/v1/auth/token" \
-H "Content-Type: application/json" \
-d @request.json#!/usr/bin/env python3
"""Exchange a secret key for a short-lived access token. Python 3.10+, requests."""
import json
import os
from pathlib import Path
import requests
API_BASE = os.environ.get("RADIUMONE_API_BASE", "https://api-sandbox.radiumone.io/gateway")
def create_access_token() -> dict:
body = json.loads((Path(__file__).parent / "request.json").read_text())
if os.environ.get("RADIUMONE_SECRET_KEY"):
body["api_key"] = os.environ["RADIUMONE_SECRET_KEY"]
resp = requests.post(f"{API_BASE}/v1/auth/token", json=body, timeout=30)
payload = resp.json()
if not resp.ok:
raise RuntimeError(f"auth/token failed: {payload.get('type') or payload.get('code')} ({resp.status_code})")
# Cache access_token server-side for up to expires_in seconds; use
# refresh_token to get a new pair before it lapses.
return payload
if __name__ == "__main__":
print(json.dumps(create_access_token(), indent=2))
{
"status": "ok",
"request_id": "req_a1b2c3d4e5f6",
"data": {
"access_token": "<opaque, treat as a bearer string>",
"token_type": "Bearer",
"expires_in": 300,
"refresh_token": "r1rt_EXAMPLE_TOKEN_ONLY",
"refresh_expires_in": 3900,
"merchant_id": "8f1c2e10-4b3a-4c5d-9e6f-7a8b9c0d1e2f",
"publishable_key": "r1pk_test_0123456789abcdef",
"redirect_secret": null
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"request_id": "<string>",
"code": "<string>",
"retry_allowed": true,
"errors": [
{
"pointer": "<string>",
"parameter": "<string>",
"code": "<string>",
"detail": "<string>"
}
]
}{
"detail": "Missing or invalid Bearer token.",
"status": 401,
"title": "Authentication Required",
"type": "urn:radiumone:gateway:authentication-required"
}{
"detail": "An unexpected error occurred.",
"status": 500,
"title": "Internal Server Error",
"type": "urn:radiumone:gateway:internal-server-error"
}Body
Request body for POST /auth/token.
Full plaintext API key (e.g. r1sk_prod_... or r1sk_test_...).
14 - 128Response
Successful Response
Standard success envelope. Every successful response has this shape, with the operation's own payload under data.
The operation's result. Its shape is documented per operation; omitted on responses that carry no payload.
Show child attributes
Show child attributes
Optional human-readable note. Omitted from the response when not set, which is the case for every payment operation today. Never parse it.
Correlation ID for this HTTP request, for logs and support. Send your own in the X-Request-Id header (letters, digits and hyphens, up to 36 characters -- other characters are stripped) or the gateway generates one. This is NOT the request_id idempotency key you send in a transaction body; the two are unrelated.
Always ok on a successful (2xx) response. Errors use a different body shape entirely (RFC 9457 problem details), so branch on the HTTP status code, not on this field.