Skip to content

Exchange client credentials for an access token

POST
/apiauth
curl --request POST \
--url https://api2.recruso.co.uk/apiauth \
--header 'Content-Type: application/json' \
--data '{ "clientId": "42.0f7b9c2e-8a41-4d6b-9f30-1c5ea7b8d902", "clientSecret": "cs_RVhBTVBMRS1PTkxZLW5vdC1hLXJlYWwtc2VjcmV0LTAwMDAwMDAwMDAwMDAwMDAw", "grantType": "client_credentials" }'

Exchanges the client id and secret issued to your API app for an access token. Every business operation in this API requires the resulting token in an Authorization: Bearer {token} header.

No sign-in is required. The client id and secret go in the request body, not the header, and authenticate the call on their own. Both are issued from the Recruso Developer Console, not through this API.

grantType must be client_credentials. The token is bound to the agency that owns the API app, which is what scopes every subsequent request — you never pass an agency id yourself. Writes are attributed to the Recruso user the app belongs to.

An unknown client id, a wrong secret, a revoked or expired credential, an inactive app, a caller outside the app’s configured IP allow-list, or an app whose owning user has been disabled all return 401 without distinguishing between them.

This endpoint is rate limited. Read expiresIn and request a new token only once the current one elapses — exchanging credentials before every call returns 429.

Access. This endpoint does not require authentication.

  • None
Media typeapplication/json

Client-credentials token request.

object
clientId
required

The client id of the credential issued to your API app. Treat it as opaque: copy the whole value from the Developer Console rather than assembling or editing it, because every character is significant and altering any part only causes the exchange to fail. It is issued as a pair with the client secret, so a new secret comes with a new client id. It is not a secret itself and grants nothing on its own.

string
Example
42.0f7b9c2e-8a41-4d6b-9f30-1c5ea7b8d902
clientSecret
required

The secret paired with ClientId. Shown once, at issue, and never retrievable afterwards. Never embed this in a browser or mobile client — exchange it server-side and keep the resulting token there.

string
Example
cs_RVhBTVBMRS1PTkxZLW5vdC1hLXJlYWwtc2VjcmV0LTAwMDAwMDAwMDAwMDAwMDAw
grantType
required

Must be client_credentials. No other grant type is supported, and any other value is rejected with 400 before the credential is looked up.

string
Example
client_credentials

OK

Media typeapplication/json

A successfully issued access token.

object
accessToken
required

The bearer token to send as Authorization: Bearer {token} on every other request. It is bound to the agency that owns the API app, which is what scopes each request — there is no agency parameter anywhere in this API.

string
expiresIn
required

Lifetime of the token in seconds. Read this rather than hardcoding a value — it is the authoritative figure and it can change. Request a new token once it elapses, not before every call: this endpoint is rate limited.

integer format: int32
tokenType
required

The token scheme. Always Bearer.

string
Example
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvd25lcl9pZCI6IjQyIn0.J1v3xQ8pN2mKb7Yc4Fd9aR",
"expiresIn": 3600,
"tokenType": "Bearer"
}

Bad Request

Media typeapplication/problem+json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Unauthorized

Too Many Requests

Media typeapplication/problem+json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}