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

# Server-to-Server Authentication

> Authenticate backend services to make API requests on behalf of devices

## Overview

Server-to-Server (S2S) authentication enables your backend services to make authenticated API requests to Firmly APIs. This method is designed for backend integrations where your server communicates directly with Firmly's APIs.

## Required Headers

<ParamField header="x-firmly-authorization" type="string" required>
  Server-to-server secret token provisioned by Firmly. This is **not** your APPID — it is a dedicated secret mapped internally to your tenant for request isolation.
</ParamField>

<ParamField header="x-firmly-device-id" type="string" required>
  The device identifier of the client making the request. Your backend passes this through when making API calls on behalf of a client device.
</ParamField>

### Device ID

The `x-firmly-device-id` is used for cart isolation and session management. Pass through your client's device ID when making API calls on their behalf.

### Device ID Requirements

| Rule               | Requirement                   |
| ------------------ | ----------------------------- |
| Presence           | Must be present and non-empty |
| Max Length         | 256 characters                |
| Allowed Characters | `a-z`, `A-Z`, `0-9`, `-`, `_` |

**Valid Examples:**

* `user-12345`
* `session_abc123`
* `82b10522-5483-4719-b599-6d78b12827f0`

**Invalid Examples:**

* Empty string
* `user.id` (period not allowed)
* `user id` (space not allowed)

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.firmly.work/api/v1/discovery/search \
    -H "x-firmly-authorization: YOUR_S2S_SECRET" \
    -H "x-firmly-device-id: user-12345" \
    -H "Content-Type: application/json" \
    -d '{"query": "running shoes"}'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.firmly.work/api/v1/discovery/search', {
    method: 'POST',
    headers: {
      'x-firmly-authorization': s2sSecret, // S2S secret (not APPID)
      'x-firmly-device-id': clientDeviceId,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ query: 'running shoes' })
  });

  const results = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.firmly.work/api/v1/discovery/search',
      headers={
          'x-firmly-authorization': s2s_secret,  # S2S secret (not APPID)
          'x-firmly-device-id': client_device_id,
          'Content-Type': 'application/json'
      },
      json={'query': 'running shoes'}
  )

  results = response.json()
  ```
</CodeGroup>

## Error Responses

<Accordion title="400 Bad Request - Missing Device ID">
  The `x-firmly-device-id` header is missing or empty.

  ```json theme={null}
  {
    "error": "BadRequest",
    "message": "Missing x-firmly-device-id header"
  }
  ```
</Accordion>

<Accordion title="400 Bad Request - Invalid Device ID Format">
  The device ID exceeds 256 characters or contains invalid characters.

  ```json theme={null}
  {
    "error": "BadRequest",
    "message": "Invalid format for x-firmly-device-id header"
  }
  ```
</Accordion>

<Accordion title="401 Unauthorized - Invalid Token">
  The S2S secret token is missing, malformed, or not found in Firmly's system.

  ```json theme={null}
  {
    "error": "InvalidAPIToken",
    "message": "Invalid or missing API token"
  }
  ```
</Accordion>

## Supported Endpoints

Server-to-Server authentication is supported on:

* [Discovery Search](/api-reference/discovery/search)
* [Discovery Options](/api-reference/discovery/options)

## Next Steps

* [Search Products](/api-reference/discovery/search) - Search for products using S2S auth
* [Get Search Options](/api-reference/discovery/options) - Retrieve filter options

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.firmly.work/api/v1/discovery/search \
    -H "x-firmly-authorization: YOUR_S2S_SECRET" \
    -H "x-firmly-device-id: user-12345" \
    -H "Content-Type: application/json" \
    -d '{"query": "running shoes"}'
  ```
</RequestExample>
