Quickstart

What you'll build: in about five minutes you'll authenticate, search for a company by name, and fetch its full profile — three API calls, each feeding the next.

Prerequisites

  • A Grand API client_id and client_secret. Don't have them? Email support@heygrand.com.
  • A terminal with curl and jq installed (or use the Python / Node examples below).

Export your credentials as environment variables so the snippets below run as-is:

export GRAND_CLIENT_ID="your-client-id"
export GRAND_CLIENT_SECRET="your-client-secret"

Exchange your client credentials for a short-lived bearer token.

TOKEN=$(curl -s -X POST https://public-api.heygrand.com/v1/oauth/token \
  -H 'Content-Type: application/json' \
  -d "{
    \"grant_type\": \"client_credentials\",
    \"client_id\": \"$GRAND_CLIENT_ID\",
    \"client_secret\": \"$GRAND_CLIENT_SECRET\"
  }" | jq -r '.access_token')

echo "$TOKEN"
import os, requests

resp = requests.post(
    "https://public-api.heygrand.com/v1/oauth/token",
    json={
        "grant_type": "client_credentials",
        "client_id": os.environ["GRAND_CLIENT_ID"],
        "client_secret": os.environ["GRAND_CLIENT_SECRET"],
    },
)
resp.raise_for_status()
token = resp.json()["access_token"]
print(token)
const resp = await fetch("https://public-api.heygrand.com/v1/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    grant_type: "client_credentials",
    client_id: process.env.GRAND_CLIENT_ID,
    client_secret: process.env.GRAND_CLIENT_SECRET,
  }),
});
if (!resp.ok) throw new Error(`Token request failed: ${resp.status}`);
const { access_token: token } = await resp.json();
console.log(token);

The response contains your token and its lifetime in seconds:

{
  "access_token": "eyJraWQiOiJ...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Tokens are valid for one hour and there is no refresh token. Cache the token and reuse it until it's close to expiring, then request a new one. See Authentication for the recommended pattern.

Search by name within a jurisdiction, passing the token in the Authorization header.

curl -s -H "Authorization: Bearer $TOKEN" \
  "https://public-api.heygrand.com/v1/search?q=Acme%20Trading&jurisdiction=GB&pageSize=5"

You'll get back a list of matches. The field you need next is companyNumber:

{
  "results": [
    {
      "name": "Acme Trading Ltd",
      "companyNumber": "12345678",
      "jurisdiction": "GB",
      "status": "Active",
      "address": "123 Example Street, London, EC1A 1BB"
    }
  ],
  "total": 1
}

Several companies can share a similar name. Use the status and address fields to pick the right one before fetching its profile.

Use the companyNumber and jurisdiction from the search result:

curl -s -H "Authorization: Bearer $TOKEN" \
  "https://public-api.heygrand.com/v1/profile/12345678?jurisdiction=GB"
{
  "name": "Acme Trading Ltd",
  "registrationNumber": "12345678",
  "jurisdiction": "GB",
  "tradingStatus": "ACTIVE"
}

That's it — you've authenticated, searched, and retrieved a company profile. 🎉

Next steps

The full recipe, with disambiguation and production-ready error handling. Understand every status code and how to recover. Token lifecycle, caching, and auth errors.

Grand Public API