Skip to main content

Authentication & Signing

Accessing OristaPay Open APIs requires dual authentication:
  • OAuth2 Access Token — proves the caller’s identity
  • HMAC Request Signature — proves the request has not been tampered with
Every request must pass both layers of verification. Failure of either results in 401 Unauthorized.

1. Obtain Access Token

Standard OAuth2 client_credentials flow. Request
POST /realms/digitalasset/protocol/openid-connect/token HTTP/1.1
Host: auth.uat.rdezlink.tech
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id={api_key}
&client_secret={api_secret}
Response
{
  "access_token": "eyJhbGciOi...",
  "token_type":   "Bearer",
  "expires_in":   300
}
Usage Constraints
  • access_token can be reused within expires_in seconds. Cache it and refresh proactively 30 seconds before expiry.
  • access_token must be issued by the OAuth client corresponding to X-Api-Key.
Using merchant A’s api_key with merchant B’s access_token will be rejected.

2. Request Signature Algorithm

String to Sign
string_to_sign = METHOD + PATH + TIMESTAMP + NONCE + SHA256_HEX(BODY)
Signature Calculation
signature = HEX( HMAC_SHA256( sign_secret, string_to_sign ) )
Field Definitions
ElementDefinition
METHODHTTP method, uppercase, e.g. POST
PATHAPI path without domain and query, e.g. /api/v1/wallet/list
TIMESTAMP13-digit UTC millisecond timestamp string, must match X-Timestamp exactly
NONCEUnique random string for this request, must match X-Nonce exactly. Recommended: 32 hex characters
BODYRaw request body bytes; empty string when no body (SHA256_HEX("") = e3b0c442...b855)
Reference Implementations
import hashlib
import hmac

def sign(method: str, path: str, ts: str, nonce: str,
         body: str, sign_secret: str) -> str:
    body_hash = hashlib.sha256(body.encode()).hexdigest()
    to_sign   = method + path + ts + nonce + body_hash
    return hmac.new(sign_secret.encode(),
                    to_sign.encode(),
                    hashlib.sha256).hexdigest()

3. Request Header Specification

All business requests must carry the following headers:
HeaderRequiredDescription
AuthorizationBearer {access_token}
X-Api-KeyYour api_key
X-TimestampUTC millisecond timestamp, ±5 minutes tolerance
X-NonceUnique random string, must not be reused within 5 minutes under the same api_key
X-SignatureSignature computed per §2
Content-TypeAlways application/json; charset=utf-8

Request & Response Conventions

Protocol Specification
ItemSpecification
TransportHTTPS (TLS 1.2+)
MethodPOST
CharsetUTF-8
FormatJSON
Field namingcamelCase
TimestampMilliseconds; string or number accepted in request, number in response

Response Envelope

All responses use a single-layer JSON { code, message, data? }, returned by the downstream business service without additional gateway wrapping. Success (Business OK) Business code code = 1, business data in data:
{
  "code":    1,
  "message": "Success",
  "data":    { /* business data; array for list endpoints */ }
}
Business / Downstream Error Downstream business errors still return HTTP 200, with error details expressed by code / message:
{
  "code":    <non-1 integer>,
  "message": "<failure reason>"
}
When downstream gRPC is unreachable or times out, HTTP status remains 200, code is a negative integer (negated gRPC StatusCode, e.g. -14 for UNAVAILABLE), with connection error details in message. Gateway-Level Error Route not found, internal gateway errors, missing descriptors, etc. HTTP status uses the corresponding error code (e.g. 400 / 404 / 500 / 502), with response body still using {code, message}:
{
  "code": 404,
  "message": "route not found"
}
  • HTTP status reflects transport layer results: 2xx means the request was successfully delivered and converted; non-2xx indicates a gateway-side error
  • Business code code reflects business layer results: 1 means business success with result in data; other values are business error codes with reason in message
  • How to determine success: HTTP 2xx + business code == 1. Both conditions must be met
  • Authentication errors: Any failure in Authorization / X-Signature / X-Timestamp / X-Nonce returns HTTP 401 with {"code":401,"message":"Unauthorized"}

Error Handling

HTTP Status Codes & Business Codes

All responses use the single-layer envelope {code, message, data?}. HTTP status reflects gateway/transport results; business code code reflects business processing results.
HTTP StatusMeaningResponse BodyAction
200 + code == 1Business success{code:1, message, data}Read business fields from data
200 + code != 1Downstream business error{code, message}Handle based on message
200 + code < 0gRPC error after delivery{code, message} (code is negated gRPC status)Check downstream, retry if needed
400Invalid request body or parameters{code, message}Fix and retry
401Authentication failed (OAuth or signature){code:401, message}Follow the troubleshooting checklist below
404Endpoint not found{code, message}Verify the path
429Rate limit triggered{code, message, ...}Back off and retry
5xxGateway or downstream service error{code, message}Exponential backoff and retry

Authentication Failure Checklist

All authentication errors return:
{ "code": 401, "message": "Unauthorized" }
Troubleshoot in this order:
  1. Is the token valid? — Has it expired? Was it issued by the current api_key?
  2. Does the signature match? — Do METHOD / PATH / BODY match the actual request?
  3. Is the timestamp within the window? — Is the local clock synchronized with NTP?
  4. Is the nonce unique? — Must not be reused within 5 minutes under the same api_key.

Rate Limiting

ItemValue
DimensionPer api_key
Default quota600 requests / minute
Exceeded responseHTTP 429
Rate Limit Exceeded Response Example
{
  "code":      429,
  "message":   "rate limit exceeded",
  "limit":     600,
  "window_ms": 60000
}
For higher quotas, contact your account manager. Adjustments take effect the following minute.

Security Recommendations

TopicBest Practice
Key managementStore api_secret and sign_secret server-side only. Never expose them to frontend or mobile clients.
Credential rotationRotate regularly; contact your account manager immediately if credentials are leaked
Transport securityEnforce HTTPS, reject any client not using TLS 1.2+
Clock synchronizationUse NTP to maintain accuracy within ±1 minute to avoid false rejections
Log sanitizationNever log full api_secret / sign_secret / access_token in application logs