Skip to main content

Authentication and security

The REST API uses OAuth 2.0 client credentials for authentication. Tokens expire after 30 minutes. If your integration runs unattended (syncing products from an ERP, exporting orders on a schedule), you need to handle token renewal automatically.

This page covers how to manage authentication in production integrations. For a first-time walkthrough of getting a token, see Getting Started → Authenticate.

Token lifecycle

Your integration follows a simple cycle:

  1. Request an access token using your client_id and client_secret
  2. Use that token for API requests (up to 30 minutes)
  3. Request a new token when the current one expires

There are no refresh tokens. When a token expires, you request a completely new one using the same client credentials. This means your integration always needs access to the credentials, not just a stored token.

Requesting a token

Send a POST request to the token endpoint with your credentials:

POST https://api.helice.cloud/oauth2/token
Content-Type: application/x-www-form-urlencoded

client_id=your_client_id&client_secret=your_client_secret&grant_type=client_credentials

A successful response returns the token and its lifetime:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5...",
"expires_in": 1800,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "profile"
}
FieldDescription
access_tokenThe bearer token to use in API requests
expires_inToken lifetime in seconds (1800 = 30 minutes)
token_typeAlways Bearer
scopeToken permissions

Using the token

Include the token as a Bearer token in the Authorization header of every API request:

GET https://api.helice.cloud/v2/products?page=1&offset=10
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5...
Content-Type: application/json

Token renewal

Build a renewal buffer of about 5 minutes into your integration. Before each API call, check whether the token will expire within 5 minutes. If it will, request a new token before making the call. This prevents tokens from expiring mid-request.

For long-running sync operations that make hundreds of calls, the renewal logic should run transparently between requests without interrupting the sync.

Handling authentication errors

Not all auth errors should be retried. Your integration needs to distinguish between temporary failures and permanent ones.

Expired token (401 invalid_token)

If an API request returns 401 with error code invalid_token, the token has expired. Request a new token and retry the call once. If the retry also fails with 401, the problem is not token expiration.

{
"Error": "Token is expired or invalid",
"ErrorCode": "invalid_token"
}

Invalid credentials (401 invalid_client)

If the token request itself returns 401 with invalid_client, your credentials are wrong. Do not retry in a loop. Log the error, send an alert and stop the sync run. Retrying with the same credentials will never succeed and may trigger rate limiting.

{
"Error": "ClientId is Invalid",
"ErrorCode": "invalid_client"
}

Bad request (400 invalid_request)

If the token request returns 400, the request format is wrong. Verify that Content-Type is set to application/x-www-form-urlencoded and that all three parameters (client_id, client_secret, grant_type) are included in the request body.

{
"Error": "Unsupported grant type",
"ErrorCode": "invalid_request"
}

Insufficient permissions (403 insufficient_scope)

If an API request returns 403, the token does not have permission to access the requested resource. Check the API client permissions in the Backoffice.

Rate limiting (429)

If you receive 429, back off and retry with exponential delays. Start with a 1 second delay and double it on each retry, up to a maximum of 30 seconds. Stop retrying after 5 attempts.

Error reference

HTTP statusError codeCauseAction
400invalid_requestMalformed token requestCheck Content-Type header and request body parameters
401invalid_clientWrong credentialsVerify client_id and client_secret in the Backoffice
401invalid_tokenToken expiredRequest a new token and retry once
403insufficient_scopeMissing permissionsCheck API client permissions in the Backoffice
429rate_limit_exceededToo many requestsRetry with exponential backoff

Securing credentials

Keep your client_id and client_secret out of source code:

  • Use environment variables or a secrets manager (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault). Never hardcode credentials in your integration code or configuration files that are committed to version control.
  • Use separate credentials per environment. Create different API clients in the Backoffice for your test and production environments. This prevents test integrations from accidentally modifying production data.
  • Rotate credentials periodically. Create a new API client in the Backoffice, update your integration to use the new credentials, verify it works, then delete the old client.

See also