Getting started
API keys
Nexpay authenticates server-to-server (M2M) traffic using API keys. Each key is a pair: a public clientId and a private secret. The two are combined and sent on the X-API-Key header of every request. Browser apps authenticate differently — see Authentication for the Bearer-token flow.
Key format
Both halves of the key carry a prefix so they're easy to recognise in code and secrets stores:
clientId—nxp_ck_<24 hex chars>(32 characters total). Treat it as public — it appears in logs and audit records.secret—nxp_sk_<64 hex chars>(71 characters total). Treat it as fully private. Nexpay stores it as an HMAC-SHA256 hash and cannot return it again after creation.
Creating an API key
You can create a key from the dashboard or via the POST /v2/dev/api-keys endpoint. Either way, only a human-authenticated user (with an active dashboard session) can create keys — API keys cannot create other API keys.
Via the dashboard
- Open the Nexpay Dashboard.
- Click your avatar in the top-right corner and select Settings.
- In the API Keys section, click Create API Key.
- Enter a descriptive label (e.g. "Production Backend", "Staging Integration").
- Click Create.
- Copy both the Client ID and Secret immediately and store the secret in your secrets manager.
Via the API
You need to be signed in with a dashboard Bearer session token to call this endpoint.
curl -X POST 'https://api.nexpay.com.au/v2/dev/api-keys' \
-H 'Authorization: Bearer your-session-token' \
-H 'Content-Type: application/json' \
-d '{
"label": "Production Backend"
}'
const response = await fetch('https://api.nexpay.com.au/v2/dev/api-keys', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${sessionToken}`,
},
body: JSON.stringify({
label: 'Production Backend',
}),
});
const { data: apiKey } = await response.json();
console.log('clientId:', apiKey.clientId); // nxp_ck_787f5b97469f65c4ca97da31
console.log('secret:', apiKey.secret); // nxp_sk_b7c41bf9... — only returned once
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders(['Authorization' => 'Bearer your-session-token'])
->post('https://api.nexpay.com.au/v2/dev/api-keys', [
'label' => 'Production Backend',
]);
$apiKey = $response->json('data');
echo $apiKey['clientId']; // nxp_ck_787f5b97469f65c4ca97da31
echo $apiKey['secret']; // nxp_sk_b7c41bf9... — only returned once
The response (unwrapped from the { data } envelope) looks like this:
{
"id": "67a1b2c3d4e5f6789abcdef0",
"clientId": "nxp_ck_787f5b97469f65c4ca97da31",
"secret": "nxp_sk_b7c41bf9a02f43e6b8d12345678901234567890abcdef1234567890abcdef1234",
"tenantId": 51,
"userId": 7372,
"createdByUserId": 7372,
"label": "Production Backend",
"isActive": true,
"createdAt": "2026-06-03T10:05:06.007Z"
}
Save your secret
The secret is only returned once at creation. Nexpay stores only a hash and cannot recover it later. If you lose it, revoke the key and create a new one.
Using your API key
Combine clientId and secret with a colon (:) and send them on the X-API-Key header:
curl 'https://api.nexpay.com.au/v2/users/me' \
-H 'X-API-Key: nxp_ck_your-client-id:nxp_sk_your-secret'
const response = await fetch('https://api.nexpay.com.au/v2/users/me', {
method: 'GET',
headers: {
'X-API-Key': `${clientId}:${secret}`,
// for example: 'nxp_ck_787f5b97469f65c4ca97da31:nxp_sk_b7c41bf9a02f43e6b8d1...'
},
});
const { data: me } = await response.json();
console.log(me.email); // "api-key:nxp_ck_787f5b97469f65c4ca97da31"
console.log(me.roles); // ["APIKey"]
console.log(me.tenantId); // 51
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders(['X-API-Key' => 'nxp_ck_your-client-id:nxp_sk_your-secret'])
->get('https://api.nexpay.com.au/v2/users/me');
$me = $response->json('data');
echo $me['email']; // "api-key:nxp_ck_787f5b97469f65c4ca97da31"
echo $me['roles'][0]; // "APIKey"
echo $me['tenantId']; // 51
See Authentication for the full request-time contract, including the Bearer scheme used by browser sessions.
Listing your API keys
curl 'https://api.nexpay.com.au/v2/dev/api-keys' \
-H 'Authorization: Bearer your-session-token'
const response = await fetch('https://api.nexpay.com.au/v2/dev/api-keys', {
method: 'GET',
headers: { 'Authorization': `Bearer ${sessionToken}` },
});
const { data } = await response.json();
data.apiKeys.forEach((key) => {
console.log(key.id, key.clientId, key.label, key.isActive, key.lastUsedAt);
});
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders(['Authorization' => 'Bearer your-session-token'])
->get('https://api.nexpay.com.au/v2/dev/api-keys');
$data = $response->json('data');
foreach ($data['apiKeys'] as $key) {
echo "{$key['id']} {$key['clientId']} {$key['label']} {$key['isActive']} {$key['lastUsedAt']}";
}
Secrets are never returned by the list endpoint — only clientId, label, and metadata.
Revoking an API key
If a key is compromised or no longer needed, revoke it immediately. Any integration using a revoked key will stop working.
Via the dashboard
- Open the Nexpay Dashboard.
- Go to Settings → API Keys.
- Hover the key and click Revoke.
- Confirm the dialog.
Via the API
curl -X DELETE 'https://api.nexpay.com.au/v2/dev/api-keys/67a1b2c3d4e5f6789abcdef0' \
-H 'Authorization: Bearer your-session-token'
await fetch(`https://api.nexpay.com.au/v2/dev/api-keys/${keyId}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${sessionToken}` },
});
// Returns 204 No Content
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders(['Authorization' => 'Bearer your-session-token'])
->delete('https://api.nexpay.com.au/v2/dev/api-keys/67a1b2c3d4e5f6789abcdef0');
// Returns 204 No Content
Revoke is a soft-delete: the key is set to isActive: false and remains visible in the list endpoint for audit. Revoked keys cannot be reactivated — create a new key and update your integration to use it.
Keep your keys safe
Anyone with your clientId:secret pair can make API calls on behalf of your account, scoped to the tenant the key was issued for. Follow these practices:
- Never store secrets in version control. Use environment variables, AWS Secrets Manager, Google Secret Manager, HashiCorp Vault, etc.
- Never embed API keys in client-side code (browser, mobile) — they'd be exposed to anyone inspecting the bundle.
- Rotate keys periodically. Create the new key first, deploy it, then revoke the old one once nothing is using it (check
lastUsedAtto confirm). - Grant access only to people who need to manage keys — only human users with dashboard sessions can create or revoke keys.
- One key per integration (or per environment), with a clear
label, so you can revoke individually without taking down everything else.