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.