Appearance
Authentication
Authentication Flow
All protected endpoints require a Bearer access token. The flow is:
- Exchange your
api_key+api_secretfor a short-lived access token - Attach the token to subsequent requests via the
Authorizationheader
text
Authorization: Bearer <access_token>Tokens are valid for 4 hours. Re-issue a new token before expiry.
Authentication — POST /v1/auth/token
Exchange your API key and secret for a short-lived Bearer access token. All protected API endpoints require this token.
Request
text
POST /v1/auth/token
Content-Type: application/jsonBody Parameters
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
api_key | string | Yes | max 64 chars | Your API key identifier |
api_secret | string | Yes | max 128 chars | Your API secret |
Example
bash
curl -X POST https://heldsway.com/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{
"api_key": "hs_key_xxxxxxxxxxxxxxxx",
"api_secret": "hs_secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}'Success Response
HTTP 200 OK
json
{
"success": true,
"message": "Token issued successfully.",
"data": {
"access_token": "AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIj",
"token_type": "Bearer",
"expires_in": 14400,
"scopes": ["reports:read"]
}
}Response Fields
| Field | Type | Description |
|---|---|---|
access_token | string | Opaque token string. Use in Authorization header. |
token_type | string | Always "Bearer" |
expires_in | integer | Token lifetime in seconds (currently 14400 = 4 hours) |
scopes | string[] | Scopes this token grants access to |
Using the Token
Attach the token to all subsequent API requests via the Authorization header:
text
Authorization: Bearer <access_token>Example
bash
curl https://heldsway.com/api/v1/affiliate/analytics?section=stats \
-H "Authorization: Bearer AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfGhIj"Token Expiry & Re-issuance
- Tokens expire after 4 hours (
expires_in: 14400seconds). - There is no refresh mechanism — simply call
POST /v1/auth/tokenagain to get a new token. - Re-issue the token before it expires to avoid interruption. A safe strategy is to re-issue when less than 10 minutes remain.
Error Reference
| HTTP Status | Error Code | Cause |
|---|---|---|
401 | UNAUTHORIZED | api_key not found, or api_secret does not match |
401 | UNAUTHORIZED | API key is inactive or has expired |
403 | FORBIDDEN | The business associated with the API key is inactive |
422 | VALIDATION_ERROR | Missing or invalid request body fields |
503 | SERVICE_UNAVAILABLE | Temporary authentication service failure |
Error Response Examples
Invalid credentials (401)
json
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API credentials."
}
}Inactive API key (401)
json
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "API key is inactive or expired."
}
}Inactive business (403)
json
{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "The business associated with this API key is inactive."
}
}Validation error (422)
json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"api_key": ["The api key field is required."]
}
}
}Rate Limiting
This endpoint is throttled at 120 requests per minute per IP address. Exceeding the limit returns HTTP 429 Too Many Requests.