> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nymblecommerce.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Nymble Commerce API Authentication — Login and Token Access

> API reference for Nymble Commerce authentication: POST /api/auth/login to obtain an access token and POST /api/auth/access to enrich tokens with org claims.

The authentication endpoints let you obtain access tokens and refresh user token claims. Call these endpoints before making any other API calls — every other endpoint requires a valid token in the `Authorization` header.

***

## POST /api/auth/login

Authenticate with your organization credentials to receive a JWT access token. Use this token in the `Authorization: Bearer` header for all subsequent requests.

<Note>
  This endpoint is **rate limited to 10 requests per minute per `ClientId`**. Cache and reuse your token until it expires rather than authenticating on every request.
</Note>

### Request body

<ParamField body="OrgCode" type="string" required>
  Your organization code. You can find this in the Nymble Commerce dashboard under **Settings → API Access**.

  Example: `"org_12345"`
</ParamField>

<ParamField body="ClientId" type="string" required>
  Your API client ID. Generated when you create an API access credential.

  Example: `"sdaf43tfsdg45dg"`
</ParamField>

<ParamField body="ClientSecret" type="string" required>
  Your API client secret. Treat this like a password — never expose it in client-side code or commit it to source control.

  Example: `"QsFdas%4F1asr23tgb675%3"`
</ParamField>

### Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.achievemomentum.com/api/auth/login \
    -H "Content-Type: application/json" \
    -d '{
      "OrgCode": "org_12345",
      "ClientId": "sdaf43tfsdg45dg",
      "ClientSecret": "QsFdas%4F1asr23tgb675%3"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.achievemomentum.com/api/auth/login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      OrgCode: 'org_12345',
      ClientId: 'sdaf43tfsdg45dg',
      ClientSecret: 'QsFdas%4F1asr23tgb675%3',
    }),
  });

  const { AccessToken, ExpiresIn } = await response.json();

  // Use the token in subsequent requests
  const apiResponse = await fetch('https://api.achievemomentum.com/api/organization', {
    headers: {
      Authorization: `Bearer ${AccessToken}`,
    },
  });
  ```
</CodeGroup>

### Response fields

<ResponseField name="AccessToken" type="string">
  The access token to include in the `Authorization: Bearer` header of all subsequent requests.

  Example: `"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."`
</ResponseField>

<ResponseField name="TokenType" type="string">
  The token type identifier. Always `"api-key"`. Pass the `AccessToken` value using the `Bearer` scheme in your `Authorization` header regardless of this field.
</ResponseField>

<ResponseField name="ExpiresIn" type="integer">
  The token lifetime in seconds. Tokens are valid for **86400 seconds (24 hours)** by default. Request a new token before this window elapses.
</ResponseField>

### Example response

```json theme={null}
{
  "AccessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tLyIsInN1YiI6IjEyMzQ1Njc4OTAiLCJleHAiOjE3MzU2ODk2MDB9.fake_signature",
  "TokenType": "api-key",
  "ExpiresIn": 86400
}
```

### Error responses

| Status                  | Description                                                                                              |
| ----------------------- | -------------------------------------------------------------------------------------------------------- |
| `401 Unauthorized`      | The `ClientId` / `ClientSecret` combination is invalid, or the `OrgCode` does not match the credentials. |
| `429 Too Many Requests` | You have exceeded the rate limit of 10 requests per minute. Wait and retry.                              |

***

## POST /api/auth/access

Enriches an existing access token with organization-specific claims for a given user. Pass the organization and user identifiers in the request body; the API returns the commerce context — customer number, price tier, and currency — that Nymble Commerce will use to scope data correctly for that user.

<Note>
  This endpoint requires a valid access token in the `Authorization` header. Obtain one via `POST /api/auth/login` before calling this endpoint.
</Note>

### Authentication

```text theme={null}
Authorization: Bearer {your_access_token}
```

### Request body

<ParamField body="OrganizationId" type="string" required>
  The internal Nymble Commerce organization ID to enrich the token for. This scopes the returned claims to the correct organization.

  Example: `"6d24ab9faf9e034e881fcd97"`
</ParamField>

<ParamField body="UserId" type="string" required>
  The Nymble Commerce user ID of the user to retrieve commerce context for.

  Example: `"kp_abc123def456"`
</ParamField>

### Example request

```bash cURL theme={null}
curl -X POST https://api.achievemomentum.com/api/auth/access \
  -H "Authorization: Bearer {your_access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "OrganizationId": "6d24ab9faf9e034e881fcd97",
    "UserId": "kp_abc123def456"
  }'
```

### Response fields

<ResponseField name="CustomerNumber" type="string | null">
  The customer account number linked to this user in the specified organization. `null` if the user has no customer association.

  Example: `"C-10042"`
</ResponseField>

<ResponseField name="PriceTier" type="string | null">
  The pricing tier assigned to this user's customer account. Used to apply the correct price list on product queries.

  Example: `"Wholesale"`
</ResponseField>

<ResponseField name="CurrencyCode" type="string | null">
  The ISO 4217 currency code for this user's organization context.

  Example: `"USD"`
</ResponseField>

### Example response

```json theme={null}
{
  "CustomerNumber": "C-10042",
  "PriceTier": "Wholesale",
  "CurrencyCode": "USD"
}
```

### Error responses

| Status             | Description                                                                     |
| ------------------ | ------------------------------------------------------------------------------- |
| `401 Unauthorized` | The bearer token in the `Authorization` header is missing, expired, or invalid. |
| `400 Bad Request`  | `OrganizationId` or `UserId` is missing or malformed.                           |
