Skip to main content

Authenticate with Secret Keys

Naqood's GraphQL API uses long-lived bearer secrets that inherit the permissions of a specific organization role. Give every integration or background job its own secret so it can be revoked without interrupting other automation.

When to use API secrets

  • Server-side connectors that sync or reconcile data on a schedule
  • Back-office scripts that post documents on behalf of a customer
  • Internal automation you already manage inside the Naqood workspace

End users should keep signing in with OAuth or email links. Secrets are only for backend, service-to-service calls that can be stored in a secure vault.

Getting a secret

You can create the same type of secret through either option:

  1. OAuth Authorization Code with PKCE – follow the OAuth guide to request consent from a customer and exchange the authorization code for a secretKey.
  2. In-app key issuance – open Settings → API while signed in to the organization and create a new key.

Secrets are displayed once. Copy them immediately and store them somewhere secure such as a secrets manager or KMS-backed vault.

Sending authenticated requests

Add the secret to the Authorization header and include the customer slug in each GraphQL request so Naqood can route it to the correct organization.

curl https://app.naqood.ae/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-d '{
"operationName": "SampleQuery",
"query": "query SampleQuery($slug: Slug!) { organization(slug: $slug) { id name } }",
"variables": { "slug": "acme-co" }
}'

Required headers

HeaderValue
Content-Typeapplication/json
AuthorizationBearer YOUR_SECRET_KEY

Most mutations and queries expect a slug variable so Naqood knows which organization issued the secret.

Common error messages

MessageMeaningResolution
missing authorization headerHeader was omitted or misspelled.Ensure the header name is Authorization with a capital A.
not authenticatedThe provided credential is invalid or expired.Copy the secret exactly as issued or create a new key.
not authorizedThe key's role does not allow that resolver.Request a role with the necessary permissions or call a different organization.

Operational tips

  • Least privilege: create dedicated roles for every integration and grant only what they need.
  • Rotation: issue a new secret on a regular cadence, roll it out, then delete the old one.
  • Naming: label keys with the integration name and organization so teams know what they power.
  • Storage: keep secrets in a managed vault and never commit them to source control or logs.

Quick validation

GraphiQL, Insomnia, Postman, or curl can run a lightweight query to confirm a key works:

query Ping($slug: Slug!) {
organization(slug: $slug) {
id
name
}
}

If the request succeeds, the secret is valid and scoped to that organization. From here, move on to feature-specific guides such as Bank Ingest.