Authentication

Every request to the Statalog REST API must be authenticated. There are two supported methods: a Bearer token in the Authorization header, or an api_key query parameter. Both methods accept the same key value — choose whichever fits your use case.

API key formats

Cloud: Keys are issued per user account and follow the format st_ followed by 64 lowercase hexadecimal characters — for example, st_a3f8c2d1e4b7... (64 hex chars). The full key is 66 characters long.

Community (self-hosted): The key is whatever secret string you set in your .env file. There is no enforced format, but a long random string is strongly recommended.

Method 1: Bearer token (recommended)

Pass the key in the Authorization header using the Bearer scheme. This is the preferred method because the key does not appear in server logs or browser history.

curl https://app.statalog.com/api/v1/stats \
  -H "Authorization: Bearer st_a3f8c2d1e4b7c9f0a2b4d6e8f1c3a5b7d9e1f2a4b6c8d0e2f4a6b8c0d2e4f6a8" \
  -G -d "site_id=ST-123456"
$client = new \GuzzleHttp\Client();

$response = $client->get('https://app.statalog.com/api/v1/stats', [
    'headers' => [
        'Authorization' => 'Bearer st_a3f8c2d1e4b7c9f0a2b4d6e8f1c3a5b7d9e1f2a4b6c8d0e2f4a6b8c0d2e4f6a8',
    ],
    'query' => [
        'site_id' => 'ST-123456',
        'period'  => '30d',
    ],
]);

$data = json_decode($response->getBody(), true);
const response = await fetch(
  'https://app.statalog.com/api/v1/stats?site_id=ST-123456&period=30d',
  {
    headers: {
      Authorization: 'Bearer st_a3f8c2d1e4b7c9f0a2b4d6e8f1c3a5b7d9e1f2a4b6c8d0e2f4a6b8c0d2e4f6a8',
    },
  }
);

const data = await response.json();

Method 2: Query parameter

Append api_key= to the URL query string. This is convenient for quick testing or environments where setting headers is difficult (for example, embedding a URL in a spreadsheet formula or a simple webhook receiver).

curl "https://app.statalog.com/api/v1/stats?site_id=ST-123456&period=30d&api_key=st_a3f8c2d1e4b7c9f0..."
$response = file_get_contents(
    'https://app.statalog.com/api/v1/stats'
    . '?site_id=ST-123456&period=30d'
    . '&api_key=st_a3f8c2d1e4b7c9f0...'
);
$data = json_decode($response, true);
const key = process.env.STATALOG_API_KEY; // load from environment, not hardcoded
const url = `https://app.statalog.com/api/v1/stats?site_id=ST-123456&period=30d&api_key=${key}`;
const response = await fetch(url);
const data = await response.json();

Note that query parameter authentication exposes the key in access logs on both your end and intermediary proxies. Use Bearer token authentication for production server-to-server calls.

Generating API keys (Cloud)

  1. Log in to Statalog and navigate to Account → API Keys.
  2. Click New API Key, enter a descriptive name (for example, "Dashboard integration" or "Reporting script"), and click Create.
  3. The full key is displayed once only immediately after creation. Copy it now and store it in a secrets manager, environment variable, or password vault. It cannot be retrieved again.
  4. The key appears in the list afterwards, but only the first and last four characters are shown — enough to identify which key is which.

You can create as many keys as you need. Giving each integration its own key makes it easy to revoke one without affecting others. To revoke a key, click Revoke next to it in the list. Revocation is immediate; any in-flight request using that key will receive a 401 response.

Configuring the API key (Community / self-hosted)

The self-hosted edition uses a single API key defined in your .env file:

STATALOG_API_KEY=your-long-random-secret-here

Restart your PHP process or queue workers after changing this value. The key can be any string — use a cryptographically random value of at least 32 characters. You can generate one with:

openssl rand -hex 32

There is no UI for rotating the key in the Community edition. To rotate it, update .env, restart the application, and update any scripts that reference the old key.

Unsuccessful authentication

If the key is missing, invalid, or revoked, the API returns HTTP 401 with the following body:

{"error": "Unauthorized"}

No additional detail is provided in the response to avoid leaking information about key existence or format.

Security guidelines

Always use HTTPS. The API only accepts HTTPS connections. Sending a key over plain HTTP is rejected.

Never expose a key in client-side JavaScript. Any key present in browser-executed code can be extracted by anyone who views the page source or opens DevTools. All API calls should originate from your server, a serverless function, or another back-end environment where the key is stored as an environment variable.

Treat the key like a password. Do not commit it to source control. Do not paste it into Slack or email. Do not log it. Use environment variables or a secrets manager (AWS Secrets Manager, HashiCorp Vault, Doppler, 1Password Secrets Automation, etc.).

Rotate keys periodically. If you suspect a key has been compromised, revoke it immediately in Account → API Keys and issue a new one.

FAQ

Can I use the API key in a browser? No. If you embed a key in JavaScript that runs in the browser, any visitor to your site can read the key from the page source or the Network panel in DevTools. Use a server-side proxy: your browser calls your own API route, which calls Statalog with the key stored securely on the server.

What permissions does an API key have? API keys provide read-only access to the analytics data for the sites in your account. They cannot create or delete sites, modify settings, invite team members, or take any other write action. Billing and account data are also inaccessible via the API.

Does one key work for all my sites? Yes. A Cloud API key can query any site belonging to your account. Use the site_id parameter to specify which site you want data for. In the Community edition, the single key similarly covers all sites configured in that installation.