NC

Naijacloud

Docs

DashboardStart free

API

/

API overview

API overview

Two surfaces, one credential. The platform API is GraphQL; Naijamail is REST. Both take the same `nc_live_` key in an Authorization header, and what the key can reach depends on the scopes you gave it.

5 min read

The two surfaces

Platform APINaijamail API
StyleGraphQLREST, JSON
Endpointhttps://api.naijacloud.com/graphqlhttps://api.naijacloud.com/v1/…
CoversProjects, services, deploys, databases, domains, DNS, storageSending and tracking email
Scope neededPLATFORM_API, or a narrower one — see belowEMAIL_SEND

They are one product with one credential. A key created in Settings → API keys works against both, and you pick which parts of each it can reach when you create it.

Authenticating

Send the key as a bearer token. Nothing else is accepted — an API key in a cookie is refused, because cookies are attached by the browser automatically and that is the property CSRF exploits.

Any request

curl https://api.naijacloud.com/graphql \ -H "Authorization: Bearer $NC_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ getMyTeams { items { id name } } }"}'

getMyTeams is the first call most integrations make: almost everything else takes a teamId, and this is where you get it.

Response

{ "data": { "getMyTeams": { "items": [{ "id": "3f2b…", "name": "Acme" }] } } }
i

Hold the key in an environment variable — NC_API_KEY is the convention — and set it as a service variable rather than committing it. If you deploy the calling service on Naijacloud, it is then present on every deploy without any further setup.

Scopes

A key carries an access level and a set of resource areas. You choose the areas when you create it; the access level is inferred, because every area describes something a machine does rather than reads.

ScopeReaches
EMAIL_SENDThe Naijamail REST API, and the mail screens' GraphQL operations
DEPLOYStriggerDeploy, deployment history, build and runtime logs
DATABASESThe SQL console, saved queries, backups and restores
PLATFORM_APIEverything else — projects, environments, services, variables, domains, DNS, storage

Anything not covered by a narrower area needs PLATFORM_API. That is the default rather than an exception, and it applies to parts of the API added after your key was issued — so a narrow key does not quietly widen as the platform grows.

The split catches people out in one place worth stating plainly: creating a service needs PLATFORM_API, but deploying it needs DEPLOYS. A CI key that only ships existing services wants DEPLOYS alone; a provisioning script that creates them wants both.

Managing domains and suppression lists through the Naijamail API needs EMAIL_SEND and PLATFORM_API. Sending is correspondence; changing a verified sending domain is configuration, and a leaked send-only key should not be able to point your domain somewhere else.

What a key cannot do

  • Issue or revoke credentials. createApiToken, revokeApiToken and the Naijamail key mutations all require a signed-in human. A key can use the platform; it cannot hand out authority, so a leaked one cannot mint itself a broader replacement.
  • Reach the admin console. That is gated on an operator login and no API key can satisfy it.
  • Exceed its owner. A key is always a subset of the person who created it. If they lose access to a workspace, so does the key.
  • Reach another workspace. Keys created from the Settings card are pinned to that workspace and are refused everywhere else.

Errors

GraphQL answers 200 with an errors array — the HTTP status is about the transport, not your query. Branch on extensions.code, never on the message text.

An expired or revoked key

{ "errors": [ { "message": "Invalid API token", "extensions": { "code": "UNAUTHENTICATED" } } ], "data": null }
CodeMeans
UNAUTHENTICATEDMissing, malformed, revoked or expired key
FORBIDDENA real key without the scope or the team role for this operation
BAD_USER_INPUTYour variables failed validation — the message names the field
THROTTLEDRate limited; back off and retry

A missing scope says which one it needs, because you are holding the key and nothing is leaked by telling you:

A key scoped only to email, calling a deploy

{ "errors": [ { "message": "This API key does not have the DEPLOYS scope. Create a key with DEPLOYS in the dashboard, under Settings → API keys.", "extensions": { "code": "FORBIDDEN" } } ] }

The Naijamail API is REST and uses real status codes: 202 accepted, 401 unauthenticated, 403 scope or verification, 422 invalid body, 429 rate limited.

Rate limits

SurfaceDefault limit
Platform API300 requests per minute, per operation
Naijamail send3,000 requests per minute, per key
Creating API keys10 per hour, and only from a signed-in session

A 429 is worth retrying with backoff. A 403 is not.

Request ids

Every response carries an x-request-id header. Log it. When something goes wrong it is the one thing that lets support find your exact request rather than guessing from a timestamp.

You can supply your own to join our logs to yours — send x-request-id with at most 64 characters of A-Za-z0-9_.:- and it is echoed back. Anything else is replaced with one of ours rather than rejected, so a malformed header never fails a send.