{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-docs/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Authentication","projectTitle":"Frontline Documentation","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"authentication","__idx":0},"children":["Authentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Frontline Public API authenticates every request with a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Bearer API key"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"http","header":{"controls":{"copy":{}}},"source":"Authorization: Bearer <YOUR_API_KEY>\n","lang":"http"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Requests without an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header, with a malformed header, or with an unknown/revoked key return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]}," (see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/errors"},"children":["Errors"]},")."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"key-types","__idx":1},"children":["Key types"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Frontline issues two kinds of API key. The type determines what an endpoint can do with it."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Scope"},"children":["Scope"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Use for"},"children":["Use for"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GENERAL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Account-level. No user identity."]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Read-only integrations, dashboards, machine-to-machine sync."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USER"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Bound to a single user in the account."]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Any write that should be attributed to a person: creating agents, updating settings, publishing flows, building flow/workflow graphs, creating incoming webhooks, managing tools/variables/intents."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Most endpoints accept ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["either"]}," type. Endpoints that require a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USER"]}," key are explicitly marked in their description in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/reference/openapi"},"children":["API Reference"]}]}," (\"Requires a USER API key\")."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you call a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USER"]},"-only endpoint with a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GENERAL"]}," key, you get ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"generating-and-managing-keys","__idx":2},"children":["Generating and managing keys"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Both kinds of API key are created from inside the Frontline app, but they live in different places. Open the app, click your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["user name in the bottom-left of the sidebar"]},", and choose ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Settings"]}," — from there, the flow splits by key type."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"personal-api-key--user-","__idx":3},"children":["Personal API key (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["USER"]},")"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In the settings sidebar, under ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["My settings"]},", open ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Bring your own Agent"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Create personal API key"]},", name it (per agent / IDE is a sensible split), and confirm."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Copy the key immediately. The dashboard stores only a SHA-256 hash of the secret — it cannot be displayed again."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each user can hold up to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["5 personal keys"]}," at a time. The same screen lists existing keys with their creation date and a delete button; remove an unused key to free a slot."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"account-api-key--general-","__idx":4},"children":["Account API key (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GENERAL"]},")"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In the settings sidebar, under ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Account settings"]},", open ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Developer"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Create API key"]},", give it a memorable name, and confirm."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Copy the key immediately — same one-time-display rule as above."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Account keys are not bound to a single user, so any teammate with workspace-admin access can create or revoke them. There is no fixed per-account cap."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"rotating-and-revoking","__idx":5},"children":["Rotating and revoking"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Rotate"]},": create a new key, swap it into your client, delete the old one. There is no in-place rotation."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Revoke"]},": deleting a key invalidates it on the next request."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A revoked or deleted key returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 unauthorized"]}," with no grace period."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"verifying-a-key","__idx":6},"children":["Verifying a key"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Hit ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /public/v1/me"]}," to confirm a key is valid and inspect what it represents:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl https://prod-api.getfrontline.ai/public/v1/me \\\n  -H \"Authorization: Bearer $FRONTLINE_API_KEY\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n    \"ok\": true,\n    \"data\": {\n        \"account\": { \"id\": 1234, \"name\": \"Acme Inc.\", \"namespace\": \"acme\" },\n        \"user\": { \"id\": 56, \"email\": \"you@acme.com\" }\n    }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data.user"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GENERAL"]}," keys."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"storage-and-transport","__idx":7},"children":["Storage and transport"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Always send keys over HTTPS. The server only accepts TLS."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Never embed keys in client-side code, public repos, or analytics events."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In CI/CD, inject keys via secrets, not committed config."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Prefer one key per integration/environment so revocation has minimal blast radius."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"cli","__idx":8},"children":["CLI"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/cli"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["frontline"]}," CLI"]}," reuses the same API keys. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["frontline auth login <api-key>"]}," stores the key locally per-profile and reuses it for both the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["frontline"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["max"]}," binaries."]}]},"headings":[{"value":"Authentication","id":"authentication","depth":1},{"value":"Key types","id":"key-types","depth":2},{"value":"Generating and managing keys","id":"generating-and-managing-keys","depth":2},{"value":"Personal API key ( USER )","id":"personal-api-key--user-","depth":3},{"value":"Account API key ( GENERAL )","id":"account-api-key--general-","depth":3},{"value":"Rotating and revoking","id":"rotating-and-revoking","depth":3},{"value":"Verifying a key","id":"verifying-a-key","depth":2},{"value":"Storage and transport","id":"storage-and-transport","depth":2},{"value":"CLI","id":"cli","depth":2}],"frontmatter":{"seo":{"title":"Authentication"}},"lastModified":"2026-05-28T14:34:48.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/authentication","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}