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:
- Code verifier – a random string (43–128 characters) that you keep on the client or pass to your backend.
- 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:
- Redirect the user to Naqood with the query parameters below.
- The user signs in, selects an organization, and approves the requested role.
- Naqood redirects back to your
redirect_uriwith an authorizationcode. - Your server exchanges the code for a
secretKeyby calling the token endpoint with the original code verifier.
Step 1 – Authorization request
GET https://app.naqood.ae/oauth/authorize
| Parameter | Required | Description |
|---|---|---|
client_id | Yes | Value provided during registration |
redirect_uri | Yes | Must match one of the allow-listed URIs |
role | Yes | Permission bundle being requested (see Available roles) |
code_challenge | Yes | Base64URL(SHA256(code_verifier)) |
code_challenge_method | Yes | Always S256 |
state | Recommended | Opaque 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
Step 2 – User consent
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:
| Parameter | Description |
|---|---|
code | Single-use authorization code (valid for five minutes) |
state | Echoed 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
| Field | Required | Description |
|---|---|---|
grantType | Yes | Always authorization_code |
code | Yes | Authorization code from Step 3 |
clientId | Yes | Your OAuth client ID |
clientSecret | Yes | Your OAuth client secret |
redirectUri | Yes | Must exactly match the authorization request |
codeVerifier | Yes | Original 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.
| Role | Display name | Intended access |
|---|---|---|
admin | Administrator | Full organization management |
member | Member | Core sales and purchase workflows |
accountant | Accountant | Financial reporting and journal entries |
billing | Billing Admin | Subscription and billing settings |
sales | Sales Person | Sales 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.