Skip to content
Last updated

Authentication

The Dinie API uses OAuth2 Client Credentials for authentication. You exchange your API credentials for a short-lived access token and include that token in all requests.

Authentication flow

Overview

  1. Your server sends credentials to POST /v3/auth/token
  2. Dinie returns a short-lived JWT access token
  3. Include the token as a Bearer header in all subsequent requests

Obtaining a Token

Send a POST request with your client_id and client_secret via HTTP Basic Authentication:

import Dinie from "dinie";

// The SDK exchanges credentials and caches the token automatically.
const dinie = new Dinie({
  clientId: process.env.DINIE_CLIENT_ID,
  clientSecret: process.env.DINIE_CLIENT_SECRET,
  environment: "sandbox",
});

Response

{
  "access_token": "dinie_at_...",
  "token_type": "bearer",
  "expires_in": 3600
}
FieldDescription
access_tokenJWT token prefixed with dinie_at_. Use as a Bearer token.
token_typeAlways bearer.
expires_inToken lifetime in seconds (3600 = 1 hour).

Using Bearer Tokens

Include the token in the Authorization header of each API request:

Authorization: Bearer dinie_at_...

Warning: Never include credentials or tokens in URLs or query parameters. Always use the Authorization header.

Token Expiration and Renewal

Tokens expire after 1 hour (3600 seconds). When a token expires, the API returns a 401 error:

{
  "type": "https://api.dinie.com.br/errors/authentication-failed",
  "title": "Authentication Failed",
  "status": 401,
  "detail": "Bearer token has expired.",
  "code": "token_expired"
}

To handle expiration:

  1. Proactive renewal -- track the expires_in and request a new token before it expires (e.g., at 80% of TTL)
  2. Reactive renewal -- catch 401 responses with the token_expired code, request a new token, and resend the request

Tip: The SDKs manage token renewal automatically. They request a new token before the current one expires and transparently resend failed requests.

Automatic SDK Authentication

When you initialize the SDK with your credentials, it manages the entire token lifecycle:

  • Exchanges credentials for a token on the first API call
  • Caches the token in memory
  • Renews the token before expiration
  • Resends requests that failed due to expired tokens

You never need to call the token endpoint directly when using an SDK.

Authentication Errors

StatusCodeDescription
400missing_grant_typeMissing grant_type parameter
400unsupported_grant_typegrant_type is not client_credentials
400missing_authorizationMissing Authorization header
401invalid_clientclient_id does not exist
401invalid_client_secretclient_secret does not match
401credential_revokedCredential has been revoked
401credential_expiredCredential is past its expiration date

Security Best Practices

  1. Store secrets securely -- use environment variables or a secret manager. Never commit credentials to version control.
  2. Use server-side calls only -- never expose your client_secret in frontend code, mobile apps, or client-side JavaScript.
  3. Rotate credentials regularly -- create a new credential, update your integration, then revoke the old one. See the Credential Management section below.
  4. Separate credentials by environment -- use different credentials for sandbox and production.
  5. Monitor usage -- check the last_used_at field on your credentials to detect unauthorized use.

Credential Management

Partners can have multiple active API credentials simultaneously. This enables credential rotation without downtime -- create a new credential, update your integration, then revoke the old one.

Creating New Credentials

Create a new API key with a human-readable name and an optional expiration date.

const credential = await dinie.auth.credentials.create({
  name: "Production Key",
  expires_at: "2027-03-04T00:00:00Z",
});

// Store credential.client_secret securely -- it is shown only once.
console.log(credential.client_id);
console.log(credential.client_secret);

Response

{
  "id": "dinie_ci_550e8400e29b41d4a716446655440000",
  "client_id": "dinie_ci_550e8400e29b41d4a716446655440000",
  "client_secret": "dinie_cs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "name": "Production Key",
  "status": "active",
  "expires_at": "2027-03-04T00:00:00Z",
  "created_at": "2026-03-04T10:00:00Z",
  "updated_at": "2026-03-04T10:00:00Z"
}

Warning: The client_secret is returned only once at creation time. Store it immediately in your secret manager. It cannot be retrieved again.

FieldRequiredDescription
nameYesHuman-readable label for this key (e.g., "Production Key", "Staging Key")
expires_atNoOptional expiration date (ISO 8601). null means the credential never expires.

Listing Credentials

Retrieve all credentials for your account. Secrets are never included in list responses.

const credentials = await dinie.auth.credentials.list();

for (const cred of credentials.data) {
  console.log(cred.name, cred.status, cred.last_used_at);
}

List Response

{
  "data": [
    {
      "id": "dinie_ci_550e8400e29b41d4a716446655440000",
      "client_id": "dinie_ci_550e8400e29b41d4a716446655440000",
      "name": "Production Key",
      "status": "active",
      "expires_at": "2027-03-04T00:00:00Z",
      "created_at": "2026-03-01T10:00:00Z",
      "last_used_at": "2026-03-04T09:30:00Z"
    }
  ],
  "has_more": false
}

Revoking Credentials

Revoke a credential by client_id. Revocation takes effect immediately -- no new tokens can be issued with this credential. Already-issued tokens continue working until they expire (up to 1 hour).

await dinie.auth.credentials.del("dinie_ci_550e8400e29b41d4a716446655440000");

The response is 204 No Content with an empty body.

Info: You cannot revoke your last active credential. A partner must always have at least one active credential. Attempting to revoke the last one returns a 409 Conflict with code last_active_credential.

Rotation Best Practices

Follow this process for zero-downtime credential rotation:

  1. Create a new credential with POST /v3/auth/credentials
  2. Update your integration to use the new client_id and client_secret
  3. Verify the new credential works by requesting a token with POST /v3/auth/token
  4. Revoke the old credential with DELETE /v3/auth/credentials/{old_client_id}

During steps 1--4, all active credentials work simultaneously. There is no authentication downtime.

Tip: Set an expires_at on credentials as a safety net. Even if you forget to revoke an old credential, it will stop working after the expiration date.

EnvironmentRotation Frequency
ProductionEvery 90 days
StagingEvery 30 days or on demand

Monitor the last_used_at field to detect credentials that are no longer in use and should be revoked.