Create Token
Issues a signed JWT (JSON Web Token) valid for 60 minutes, containing the claims you supply plus standard claims (jti, iat, exp, iss) added by the server.
- Issuer (
iss):AccessPayHub - Signing algorithm:
RS256(RSA-2048)
Endpoint
POST /token
Full production URL: https://group.pay.accessacloud.com/loader/token
Header Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Content-Type | string | required | Must be application/json |
X-Api-Key | string | required | Your issued API key |
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
claims | object | required | Flat dictionary of string keys to string values. Sent verbatim into the JWT (see Claims object below) |
Claims Object
- A flat dictionary mapping string keys to string values.
- At least one entry is required — sending an empty
claimsobject returns400 Bad Request. - Claim names and values are passed through verbatim into the JWT, so use the exact names your downstream consumer expects (e.g.
sub,org_id,role). - Don't send
jti,iat,exp, oriss— the server sets those itself. If you include them, the server's values still take precedence. - Nested objects and arrays are not supported. If you need structured data, serialise it yourself (e.g. JSON-stringify into a single claim value).
Response Parameters
Status Code: 200 OK
| Parameter | Type | Description |
|---|---|---|
token | string | The full signed JWT |
Token Contents
When the returned JWT is decoded, it contains:
| Claim | Type | Description |
|---|---|---|
| (your claims) | string | Every claim you sent in the claims dictionary, exactly as sent |
iss | string | Issuer — always AccessPayHub |
jti | string | Unique token GUID (anti-replay) |
iat | number | Unix timestamp (seconds) when the token was issued |
exp | number | Unix timestamp (seconds) when the token expires (iat + 3600) |
You can decode the token (without verifying the signature) on jwt.io to inspect the claims while developing.
Example Request
{
"claims": {
"sub": "user-12345",
"org_id": "org-67890",
"role": "admin"
}
}
Example Response
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTEyMzQ1Iiwib3JnX2lkIjoib3JnLTY3ODkwIiwicm9sZSI6ImFkbWluIiwianRpIjoiOGYzMmZlMmYtYmNmMS00ZGI3LTljZTAtZGM0NWE5MWEwYjIyIiwiaWF0IjoxNzYyNTEyMDAwLCJleHAiOjE3NjI1MTU2MDAsImlzcyI6IkFjY2Vzc1BheUh1YiJ9..."
}
Decoded payload (for the example request above):
{
"sub": "user-12345",
"org_id": "org-67890",
"role": "admin",
"jti": "8f32fe2f-bcf1-4db7-9ce0-dc45a91a0b22",
"iat": 1762512000,
"exp": 1762515600,
"iss": "AccessPayHub"
}
Status Code: 400 Bad Request
Returned when the request body is missing, malformed, or claims is empty. Make sure:
- The body is valid JSON.
Content-Type: application/jsonis set.claimshas at least one entry.
{ "error": "Claims are required." }
Status Code: 401 Unauthorized
Returned when the X-Api-Key header is missing or doesn't match a configured key. Confirm you're using the correct key and that the header name is exactly X-Api-Key.
Status Code: 503 Service Unavailable
Returned when the server has no API keys configured at all — this is a server-side misconfiguration, not a problem with your request. Contact the platform team. Retrying won't help until config is fixed.
Usage Notes
- Use the returned token straight away — pass it as
Authorization: Bearer <token>to downstream services that accept JWTs issued byAccessPayHub. - The token expires 60 minutes after issuance. Cache it if you call it often, but don't cache past
exp. - There is no refresh endpoint — call
POST /tokenagain to get a new token. - Downstream services that verify the token need the matching public key. Request it from the platform team if you're integrating a verifier.
Code Samples
In all examples below, replace <your-api-key> with the API key issued to you by the platform team.
For a cURL example, see cURL.
PowerShell
$apiKey = "<your-api-key>"
$headers = @{
"Content-Type" = "application/json"
"X-Api-Key" = $apiKey
}
$body = @{
claims = @{
sub = "user-12345"
org_id = "org-67890"
role = "admin"
}
} | ConvertTo-Json
$response = Invoke-RestMethod `
-Uri "https://group.pay.accessacloud.com/loader/token" `
-Method Post `
-Headers $headers `
-Body $body
Write-Host "JWT: $($response.token)"
C# (HttpClient)
using System.Net.Http.Json;
var http = new HttpClient();
http.DefaultRequestHeaders.Add("X-Api-Key", "<your-api-key>");
var payload = new
{
claims = new Dictionary<string, string>
{
["sub"] = "user-12345",
["org_id"] = "org-67890",
["role"] = "admin"
}
};
var response = await http.PostAsJsonAsync(
"https://group.pay.accessacloud.com/loader/token",
payload);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<TokenResponse>();
Console.WriteLine(result?.Token);
record TokenResponse(string Token);
JavaScript (fetch)
const response = await fetch("https://group.pay.accessacloud.com/loader/token", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": "<your-api-key>"
},
body: JSON.stringify({
claims: {
sub: "user-12345",
org_id: "org-67890",
role: "admin"
}
})
});
if (!response.ok) {
throw new Error(`Token request failed: ${response.status}`);
}
const { token } = await response.json();
console.log(token);
FAQ
How long is a token valid?
60 minutes from the moment it's issued (exp = iat + 3600).
Can I extend the lifetime or refresh a token? No — the lifetime is fixed server-side, and there's no refresh endpoint. Just call the endpoint again to get a new one.
Can I include nested objects or arrays in claims?
No. claims is a flat dictionary of strings to strings. Both keys and values must be strings. If you need structured data, serialise it yourself (e.g. JSON-stringify into a single claim value).
What happens if I send iat, exp, or jti myself?
The server adds its own values for these. The server's standard-claim values take precedence over any you provide.
Where do I get an API key? From the platform team. Keys are issued per consumer and can be rotated on request.
My request returns 401 even though I'm sure my key is right. What now? Check, in this order:
- The header is named exactly
X-Api-Key(noX-API-KEYtypo, noAuthorization:prefix). - There's no leading/trailing whitespace or stray quotes around the value.
- The key hasn't been rotated — confirm with the platform team.
How is the token signed?
With RSA-2048 (RS256). Downstream services that verify the token need the matching public key — request it from the platform team if you're integrating a verifier.