---
description: >-
  Inyo Gateway uses OAuth 2.0 Client Credentials to authenticate all API
  requests. This page explains how to obtain and use access tokens.
---

# Authentication

## Overview

All Payment Gateway API calls (except tokenization, which uses your public key) require a Bearer token obtained via the `/oauth/token` endpoint.

**Key characteristics:**

- **Grant type**: Client Credentials (machine-to-machine)
- **Token lifetime**: Short-lived (typically 1 hour) — request a new token when expired
- **Transport**: Always use HTTPS; never send credentials over unencrypted connections
- **Storage**: Tokens should be stored securely server-side; never expose them in client-side code

## Obtaining an Access Token

```
POST /oauth/token
```

### Request

```bash
curl -X POST https://sandbox-gw.simpleps.com/oauth/token \
  -H 'Content-Type: application/json' \
  -d '{
    "clientId": "YOUR_CLIENT_ID",
    "secretId": "YOUR_CLIENT_SECRET"
  }'
```

| Field | Type | Required | Description |
|---|---|---|---|
| `clientId` | string | ✅ | Your OAuth client identifier, provided during onboarding |
| `secretId` | string | ✅ | Your OAuth client secret, provided during onboarding |

### Response (Success — 200)

```json
{
  "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "tokenType": "Bearer",
  "expiresIn": 3600
}
```

| Field | Type | Description |
|---|---|---|
| `accessToken` | string | JWT token to include in subsequent API calls |
| `tokenType` | string | Always `"Bearer"` |
| `expiresIn` | number | Token validity in seconds |

### Response (Unauthorized — 401)

```json
{
  "status": 401,
  "message": "Unauthorized request",
  "responseCode": "SE_001"
}
```

## Using the Token

Include the access token in the `Authorization` header of every API request:

```bash
curl -X POST https://sandbox-gw.simpleps.com/v2/payment \
  -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \
  -H 'Content-Type: application/json' \
  -d '{ ... }'
```

## Token Management Best Practices

1. **Cache tokens** — Reuse the same token until it expires rather than requesting a new one per API call. The authentication endpoint has a rate limit of 60 requests/minute.

2. **Handle expiry gracefully** — When you receive a `401` or `403` response, request a new token and retry the original request.

3. **Never expose credentials client-side** — The `clientId` and `secretId` must only be used from your backend server (Backend-for-Frontend pattern). The only client-side credential is the `publicKey` used for card tokenization.

4. **Rotate secrets periodically** — Contact the Inyo team to rotate your client secret if you suspect it has been compromised.

## Authentication vs. Tokenization

| Concern | Server-side (OAuth) | Client-side (Tokenizer) |
|---|---|---|
| **Credential** | `clientId` + `secretId` | `publicKey` |
| **Endpoint** | `POST /oauth/token` | `inyo.js` library |
| **Purpose** | Authenticate API calls | Tokenize card data |
| **Exposure** | Backend only | Browser (safe to expose) |

## Rate Limits

| Endpoint | Limit |
|---|---|
| Authentication (`/oauth/token`) | 60 requests/minute |
| FX rates | 200 requests/minute |
| All other authenticated endpoints | 400 requests/minute |

When rate-limited, the API returns HTTP `429`. Implement exponential backoff with jitter in your retry logic.
