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

# Authentication

> Exchange API credentials for a JWT used as `Authorization: Bearer <token>` on protected routes. Tokens expire after one hour.

## Overview

The partner authentication endpoint allows trusted third-party partners to exchange their issued API credentials for a JWT (JSON Web Token) that can be used to authenticate subsequent API requests on behalf of their clients.

## Request

### Headers

* `Content-Type: application/json`

### Body Parameters

<ParamField path="api_key" type="string" required>
  Your unique API key issued by Targeter for your approved partnership
</ParamField>

<ParamField path="api_secret" type="string" required>
  Your plain-text API secret issued by Targeter. Send the secret exactly as provided — not a bcrypt hash or other encoded form.
</ParamField>

### Example Request

```bash theme={null}
curl -X POST "https://app.targeter.tech/api/auth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "YOUR_ISSUED_PARTNER_KEY",
    "api_secret": "YOUR_ISSUED_PARTNER_SECRET"
  }'
```

Use snake\_case field names (`api_key`, `api_secret`). CamelCase names such as `apiKey` return **400**.

## Response

### Success Response (200)

<ResponseField name="access_token" type="string">
  JWT token to be used in Authorization header for subsequent requests
</ResponseField>

<ResponseField name="token_type" type="string">
  Token type (always "Bearer")
</ResponseField>

<ResponseField name="expires_in" type="integer">
  Token validity in seconds (3600 = 1 hour)
</ResponseField>

### Example Response

```json theme={null}
{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600
}
```

## Error Responses

### 400 - Invalid request payload

```json theme={null}
{
    "error": "Invalid request payload",
    "details": [
        {
            "path": ["api_key"],
            "message": "Invalid input: expected string, received undefined"
        }
    ]
}
```

### 401 - Invalid API credentials

```json theme={null}
{
    "error": "Invalid API credentials"
}
```

### 500 - Internal server error

```json theme={null}
{
    "error": "Internal server error"
}
```

## Usage Notes

* **Token Expiration**: JWT tokens expire after 1 hour for security
* **Refresh**: You must obtain a new token when the current one expires
* **Security**: Never expose your issued API secret in client-side code — these are for server-to-server communication only
* **Storage**: Store tokens securely and refresh them before expiration
* **Credentials**: Only use API credentials issued specifically to your approved partnership
* **Base URL**: Your API base URL is provided with your credentials (e.g. `https://app.targeter.tech/api`)

## Next Steps

Once you have your JWT token, you can use it to make authenticated requests on behalf of your clients:

```bash theme={null}
curl -X POST "https://app.targeter.tech/api/campaign" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
```


## OpenAPI

````yaml POST /auth/token
openapi: 3.1.0
info:
  title: Targeter REST API
  description: >-
    Partner-facing HTTP API for Targeter: obtain a JWT and create or resolve
    campaigns from external systems.
  version: 1.2.0
  contact:
    name: Targeter API Support
servers:
  - url: https://app.targeter.tech/api
    description: >-
      Targeter platform instance (your base URL is provided with your
      credentials)
security:
  - BearerAuth: []
paths:
  /auth/token:
    post:
      tags:
        - Authentication
      summary: Obtain JWT access token
      description: >-
        Exchange API credentials for a JWT used as `Authorization: Bearer
        <token>` on protected routes. Tokens expire after one hour.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - api_key
                - api_secret
              properties:
                api_key:
                  type: string
                  description: API key issued for your partnership
                  example: YOUR_ISSUED_PARTNER_KEY
                api_secret:
                  type: string
                  description: >-
                    Plain-text API secret issued for your partnership (not a
                    bcrypt hash)
                  example: YOUR_ISSUED_PARTNER_SECRET
      responses:
        '200':
          description: Successfully authenticated
          content:
            application/json:
              schema:
                type: object
                required:
                  - access_token
                  - token_type
                  - expires_in
                properties:
                  access_token:
                    type: string
                    description: JWT for the Authorization header
                    example: eyJhbGciOiJIUzI1NiIsInR5cCI6...
                  token_type:
                    type: string
                    example: Bearer
                  expires_in:
                    type: integer
                    description: Token lifetime in seconds
                    example: 3600
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Invalid request payload
                details:
                  - path:
                      - api_key
                    message: 'Invalid input: expected string, received undefined'
        '401':
          description: Invalid API credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Invalid API credentials
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security: []
components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
          description: Error message
          example: Missing required field
        details:
          type: array
          description: Validation issues (Zod), when returned by the server
          items:
            type: object
            properties:
              path:
                type: array
                items:
                  type: string
                example:
                  - source
                  - reference_id
              message:
                type: string
                example: Reference ID is required
            required:
              - message
      required:
        - error
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Use `Authorization: Bearer <token>`. Obtain the token from `POST
        /auth/token`.

````