Aller au contenu principal

Authentication and API keys

Authenticated endpoints take a bearer token:

Authorization: Bearer stfv_your_key_here

Keys always start with stfv_. Create one at opcua-modeler.sterfive.io → Settings → API Keys ↗.

export OPCUA_MODELER_API_KEY=stfv_…

curl -X POST https://api.opcua-modeler.sterfive.io/api/v1/generate \
-H "Authorization: Bearer $OPCUA_MODELER_API_KEY" \
-H "Content-Type: text/yaml" \
--data-binary @model.yaml

The key is shown once, when it is created. It is stored only as a hash, so if you lose it nobody can recover it — rotate to get a new one.

Keys expire after 30 days

Every self-served key is issued for 30 days. This is deliberate: it keeps abandoned keys from living forever, and it is why renewal is free and takes one click.

Three things follow from it.

You get warned before it happens. Inside the last 7 days, every successful response carries:

X-Key-Expires-At: 2026-03-01T09:00:00.000Z
X-Key-Expires-In-Days: 4

Read those headers in your client and you will never be surprised.

An expired key is refused distinctly. Not a generic 401 — a 403 carrying a machine-readable code, so a client can tell "renew this" apart from "this key was never valid":

{
"code": "key_expired",
"error": "API key expired on 2026-03-01T09:00:00.000Z.",
"hint": "Rotate your key at https://opcua-modeler.sterfive.io/app/settings/api"
}

This fires even on endpoints that would serve an anonymous caller. Presenting a stale credential means you believe you are authenticated, so the renewal prompt wins over a silent downgrade to the anonymous quota.

Renewal is a rotation. On the API-keys page:

  • Rotate replaces the secret and keeps the current expiry date. Use it if a key leaks.
  • Rotate & extend replaces the secret and grants a fresh 30 days.

The extension window

Rotate & extend is only available in the last 7 days before expiry, or at any time after the key has already expired. Earlier attempts are refused:

{
"code": "extend_not_yet",
"error": "Extension is available during the last 7 days before expiry (from 2026-02-22T09:00:00.000Z). Use a plain rotate to replace the secret now.",
"availableAt": "2026-02-22T09:00:00.000Z"
}

with status 409. Extending always resets to now + 30 days, so extending early would cost you the unused days — the window simply makes that explicit.

A lapsed key can always be extended. Letting a key expire does not lock you out.

Creating a new key does not reset the clock

Deleting a key and creating another carries the previous expiry window forward. A fresh 30 days is granted only when you would already have been allowed to extend. Delete-and-recreate is not a way around the window.

Two other refusals you may meet, both 409:

  • rotate_expired_use_extend — a plain rotate of an already-expired key would hand back a secret that fails on first use. Use Rotate & extend.
  • A key revoked concurrently in another tab; nothing was rotated, retry.

Non-expiring keys

expiresAt: null marks a legacy or enterprise key that never expires. These are granted out of band and cannot be self-served — the API-keys page shows them as Never and hides the extend action, since there is nothing to extend.

Browser sessions

A few endpoints (/api/v1/try-server, the AI endpoints) also accept a signed-in browser session instead of a key, so the web editor can call them directly. Session callers are burst-limited like everyone else but do not consume a key's daily quota. This is not available to programmatic clients — use a key.