Docs
Firmly Agentic Commerce
Set theme to dark (⇧+D)

Server-to-Server Authentication

​​ 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

  • x-firmly-authorization (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. You may send it either as x-firmly-authorization: <secret> or as the standard Authorization: Bearer <secret> — the two forms are equivalent.

  • x-firmly-device-id (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.

​​ 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


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"}'

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();

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()

​​ Supported Endpoints

Server-to-Server authentication is accepted across the entire cart and checkout surface — v1 and v2 — plus Discovery and read-only catalog. In practice this is the same set of routes a browser-session or App ID caller can reach, minus the six device-scoped session routes listed under “Not accepted” below. On every accepted route, send the S2S secret plus x-firmly-device-id.

Accepted (S2S secret + x-firmly-device-id):

Not accepted — device JWT only. These six device-scoped session routes require a device JWT; the S2S secret is rejected. Use Browser Session auth instead:

​​ Next Steps

​​ Error Responses

Errors return a JSON body with code, error, and description. Program against the error value — descriptions are human-readable and may change.

400 — BadRequest

The x-firmly-device-id header is missing, empty, exceeds 256 characters, or contains characters outside a-z, A-Z, 0-9, -, _.


{ "code": 400, "error": "BadRequest", "description": "Bad request." }
400 — InvalidAPIToken

The S2S secret token is missing, malformed, or not recognized.


{ "code": 400, "error": "InvalidAPIToken", "description": "API token is invalid." }