Skip to main content

OAuth 2.0 Integration

Naqood supports a standards-based OAuth 2.0 Authorization Code flow with PKCE so partners can request scoped access to a customer's organization without handling their credentials. The flow issues the same long-lived secret that powers every GraphQL call.

Register your application

Reach out to your Naqood account team to register an OAuth client. Share the details below so the consent screen displays accurate information:

  • Application name – visible to users during consent
  • Redirect URIs – HTTPS endpoints that can receive the authorization code
  • Description, logo, and website – optional branding shown on the consent screen

The team will return a client_id and client_secret. Keep the secret in a secure store.

Flow overview

PKCE (Proof Key for Code Exchange) adds a lightweight handshake to prevent intercepted authorization codes from being reused. Your client generates two short-lived strings:

  1. Code verifier – a random string (43–128 characters) that you keep on the client or pass to your backend.
  2. Code challenge – the Base64URL-encoded SHA-256 hash of the verifier. This is sent with the initial authorization request.

Generation outline:

verifier = random_url_safe_string(43..128 chars)
challenge = base64url(sha256(verifier))

Most OAuth libraries expose helpers to produce both values. The rest of the flow follows four steps:

  1. Redirect the user to Naqood with the query parameters below.
  2. The user signs in, selects an organization, and approves the requested role.
  3. Naqood redirects back to your redirect_uri with an authorization code.
  4. Your server exchanges the code for a secretKey by calling the token endpoint with the original code verifier.

Step 1 – Authorization request

GET https://app.naqood.ae/oauth/authorize
ParameterRequiredDescription
client_idYesValue provided during registration
redirect_uriYesMust match one of the allow-listed URIs
roleYesPermission bundle being requested (see Available roles)
code_challengeYesBase64URL(SHA256(code_verifier))
code_challenge_methodYesAlways S256
stateRecommendedOpaque value you validate during the callback

Example:

https://app.naqood.ae/oauth/authorize?client_id=app_12345&redirect_uri=https://myapp.com/callback&role=admin&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&state=xyz123

Naqood prompts the user to sign in (if necessary), reviews your application details, and lets the user choose which organization should grant access. The user can approve or deny your request.

Step 3 – Handle the callback

After approval Naqood redirects the browser to your redirect_uri:

ParameterDescription
codeSingle-use authorization code (valid for five minutes)
stateEchoed from your original request so you can confirm CSRF protection

Example callback:

https://myapp.com/callback?code=auth_code_abcdef123456&state=xyz123

Step 4 – Exchange the code for a secret

POST https://app.naqood.ae/api/oauth/token
Content-Type: application/json
FieldRequiredDescription
grantTypeYesAlways authorization_code
codeYesAuthorization code from Step 3
clientIdYesYour OAuth client ID
clientSecretYesYour OAuth client secret
redirectUriYesMust exactly match the authorization request
codeVerifierYesOriginal code verifier string
curl -X POST https://app.naqood.ae/api/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grantType": "authorization_code",
"code": "auth_code_abcdef123456",
"clientId": "app_12345",
"clientSecret": "sec_987654321",
"redirectUri": "https://myapp.com/callback",
"codeVerifier": "your_generated_code_verifier_string"
}'

Successful responses return JSON similar to:

{
"secretKey": "YOUR_SECRET_KEY",
"tokenType": "Bearer",
"organizationSlug": "acme-co"
}

Store the secretKey exactly as returned. Use it in the Authorization: Bearer header described in the Authentication guide. The organizationSlug tells you which workspace granted access so you can immediately scope GraphQL calls.

Available roles

Request the least-privileged role that still lets your integration operate. Standard roles are shown below; organizations may add custom roles and share the slug with you if needed.

RoleDisplay nameIntended access
adminAdministratorFull organization management
memberMemberCore sales and purchase workflows
accountantAccountantFinancial reporting and journal entries
billingBilling AdminSubscription and billing settings
salesSales PersonSales pipeline and invoicing

Next steps

Use the returned secret to call GraphQL endpoints with the standard bearer header. Continue with the Authentication and Bank Ingest guides for concrete API examples.