Gateway API Reference
The gateway proxies requests from your application through OneHazel to supplier APIs. It handles authentication, schema translation, rate limiting, and circuit breaking automatically.
Endpoint: POST /functions/v1/gateway
Authentication: Authorization: Bearer oh_live_...
How it works
- You send an operation name and parameters in OneHazel's canonical format
- The gateway looks up the connection and its connector blueprint
- Parameters are translated from canonical to provider field names via the schema mapping
- Authentication credentials are applied (decrypted from the connection config)
- The request is sent to the provider's API endpoint
- The response is translated back to canonical format
- The call is logged to
gateway_logs
Request
POST /functions/v1/gateway| Field | Type | Required | Description |
|---|---|---|---|
connectionId | string | Yes | ID of an active connection |
operation | string | Yes | Operation name in entity.action format |
params | object | No | Parameters in canonical format |
Operation format
Operations use a dot-notation format: entity.action. The action keyword determines the HTTP method:
| Action keyword | HTTP Method |
|---|---|
verify, check, get, list, fetch, read, search, find, status, balance | GET |
create, deposit, submit, send, initiate, register, start | POST |
update, modify, edit | PATCH |
replace, set | PUT |
delete, remove, cancel, revoke | DELETE |
If no matching keyword is found, the default method is POST.
Example: Verify a player's identity
curl -X POST https://api.onehazel.com/gateway \
-H "Authorization: Bearer oh_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"connectionId": "conn_abc123",
"operation": "applicant.verify",
"params": {
"externalUserId": "player_12345",
"firstName": "James",
"lastName": "Wilson",
"dateOfBirth": "1992-03-15",
"country": "GBR"
}
}'Example: Create a payment
curl -X POST https://api.onehazel.com/gateway \
-H "Authorization: Bearer oh_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"connectionId": "conn_stripe_xyz",
"operation": "payment.create",
"params": {
"amount": 5000,
"currency": "gbp",
"description": "Player deposit",
"metadata": {
"player_id": "player_12345"
}
}
}'Example: Get account balance
curl -X POST https://api.onehazel.com/gateway \
-H "Authorization: Bearer oh_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"connectionId": "conn_payment_456",
"operation": "account.balance",
"params": {}
}'Response
Success
{
"success": true,
"data": {
"id": "pi_3abc123",
"status": "succeeded",
"amount": 5000,
"currency": "gbp"
},
"latencyMs": 342
}The data field contains the provider's response translated to canonical field names via the connector's schema mapping. Fields without a mapping are passed through unchanged.
Provider error
When the provider returns a non-2xx status:
{
"success": false,
"error": {
"code": "PROVIDER_ERROR",
"message": "Provider returned 422"
},
"data": {
"error": "Invalid card number"
},
"latencyMs": 156
}HTTP status: 502
Schema translation
The gateway performs bidirectional field name translation using the connector's schemaMap:
- Outbound (canonical to provider): Your
paramsfields are translated to provider field names before sending the request - Inbound (provider to canonical): The provider's response fields are translated back to canonical names
Fields without a mapping in either direction are passed through unchanged.
Authentication
Connection credentials are stored encrypted (AES-256-GCM) and decrypted at request time. The gateway applies auth based on the connector's OpenAPI securitySchemes:
| Security Scheme | How it's applied |
|---|---|
apiKey (header) | Sets the specified header name with the API key value |
apiKey (query) | Adds the key as a query parameter |
http (bearer) | Sets Authorization: Bearer <token> |
http (basic) | Sets Authorization: Basic <base64(user:pass)> |
| HMAC | Signs the request body with HMAC-SHA256, sets X-Signature and X-Signature-Algorithm headers |
If no securitySchemes are defined in the OpenAPI spec, the gateway falls back to sending a Bearer token using the first available credential from the connection config.
Circuit breaker
The gateway includes an in-memory circuit breaker per provider. If a provider returns too many 5xx errors, the circuit opens and subsequent requests are rejected immediately with:
{
"success": false,
"error": {
"code": "CIRCUIT_OPEN",
"message": "Provider circuit breaker is open — too many recent failures. Retry in 30s."
},
"latencyMs": 1
}HTTP status: 503, with Retry-After: 30 header.
Successful responses reset the circuit breaker.
Operation matching
The gateway matches your operation string to an OpenAPI path in the connector's spec using a scoring algorithm:
- The entity name (first part before the dot) is matched against URL path segments
- The action keyword is matched against HTTP methods and path/summary/operationId
- The highest-scoring match is selected
If no match is found:
{
"success": false,
"error": {
"code": "OPERATION_NOT_FOUND",
"message": "No matching endpoint found for operation \"foo.bar\""
}
}Events
Every gateway call emits an event:
gateway.request.completed— for successful calls (provider returned 2xx)gateway.request.failed— for failed calls (provider returned non-2xx)
These events can trigger workflows.
Error codes
| HTTP Status | Error Code | Description |
|---|---|---|
400 | MISSING_FIELDS | connectionId or operation is missing |
400 | CONNECTION_INACTIVE | Connection exists but is not active |
400 | BLUEPRINT_NO_SPEC | Connector has no OpenAPI spec |
401 | AUTH_MISSING | No Authorization header |
401 | AUTH_INVALID | API key not recognised |
401 | AUTH_REVOKED | API key has been revoked |
404 | CONNECTION_NOT_FOUND | Connection not found or belongs to another operator |
404 | CONNECTOR_NOT_FOUND | Connector blueprint not found |
404 | OPERATION_NOT_FOUND | No endpoint matches the operation |
405 | METHOD_NOT_ALLOWED | Only POST is accepted |
429 | RATE_LIMITED | Rate limit exceeded for gateway:execute |
502 | PROVIDER_ERROR | Provider returned a non-2xx response |
503 | CIRCUIT_OPEN | Circuit breaker is open |
500 | INTERNAL_ERROR | Server error |