Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.
API keys are managed in the
Screenshotly dashboard. There is no
public API for creating or revoking keys: an API key cannot mint, list, or
revoke other keys.
Key facts
Property
Behavior
Format
scr_ followed by 64 hexadecimal characters
Storage
Only a SHA-256 hash is stored; the plaintext is shown once
Scope
One workspace; the key can read only that workspace’s jobs and captures
Expiry
30 days after creation for keys generated in the dashboard
Limit
Up to 10 active keys per workspace
Status
ACTIVE, EXPIRED, or REVOKED
Rate limits
Shared by the workspace owner’s account; extra keys do not add throughput or quota
In Workspace, choose the personal or team workspace the key should belong to.
Enter a name that says where the key will live, such as production-api or
github-actions. The name is optional; unnamed keys are called
Default API Key.
Click Generate New Key, copy the key, and store it in your secret manager.
It is not shown again.
Each key in the list shows its status, creation date, expiry date, and the
number of successful requests made with it.
Store keys safely
Load the key from the environment or a secret manager at runtime:
const apiKey = process.env.SCREENSHOTLY_API_KEY;if (!apiKey) throw new Error('SCREENSHOTLY_API_KEY is not set');
import osapi_key = os.environ.get("SCREENSHOTLY_API_KEY")if not api_key: raise RuntimeError("SCREENSHOTLY_API_KEY is not set")
Use a separate key for each environment and system: local development, CI,
staging, and production. Revoking one does not interrupt the others.
Keep keys out of source control, client-side bundles, mobile apps, logs, and
error trackers.
Give team members access through a team workspace
instead of sharing one personal key.
Rotate a key
Because dashboard keys expire after 30 days, plan rotation as a routine task:
Generate a new key in the same workspace.
Update the secret in every system that uses the old key, and redeploy.
Confirm traffic is flowing with the new key: its request count in the
dashboard increases.
Revoke the old key.
Set a reminder before the expiry date shown in the dashboard. When a key
expires, requests fail with 401 Invalid API key. Handle 401 in your client
by alerting a person rather than retrying, because retries cannot succeed.
Revoke a key
Click the delete icon next to a key in
Dashboard → API keys. Revocation
takes effect immediately and cannot be undone; the next request with that key
returns 401.A key can be revoked by the member who created it, or by an owner or admin of
the key’s workspace.
If a key is exposed (committed to a repository, pasted into a ticket, or
shipped in client code), revoke it first, then create a replacement. Do not
wait for it to expire.
Troubleshooting
Response
Meaning
What to do
401 Invalid API key
The key is unknown, revoked, or expired.
Check the key’s status in the dashboard and rotate it.
401 API key is required…
No x-api-key or Authorization header was sent.
Check that your client sets the header.
403 Email verification required
The workspace owner’s email address is not verified.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Screenshotly","colors":{"primary":"#2563eb","light":"#3b82f6","dark":"#1d4ed8"},"api":{"playground":{"display":"simple"},"mdx":{"auth":{"method":"key","name":"x-api-key"},"server":"https://screenshotly.app"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"screenshotly","hasAudioNarration":false,"actualSubdomain":"screenshotly","customDomains":["docs.screenshotly.app"],"gitSource":{"type":"github","owner":"itsmeasadali","repo":"screenshotly","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{},"buildId":"6af89dd57fd385b08ebd03a5","clientVersion":"0.0.4143","searchFilterCounts":[{"language":"default","tag":"Guides","count":6},{"language":"default","tag":"Getting Started","count":3},{"language":"default","tag":"API Reference","count":2}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"guides/managing-tokens","slug":"/guides/managing-tokens","pageMetadata":{"title":"Managing API keys","description":"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.","href":"/guides/managing-tokens"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,CodeGroup,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!CodeGroup)_missingMdxReference(`CodeGroup`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`API keys are managed in the\n`,_jsx(_components.a,{href:`https://screenshotly.app/dashboard/tokens`,children:`Screenshotly dashboard`}),`. There is no\npublic API for creating or revoking keys: an API key cannot mint, list, or\nrevoke other keys.`]}),`\n`,_jsx(Heading,{level:`2`,id:`key-facts`,children:`Key facts`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Property`}),_jsx(_components.th,{children:`Behavior`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Format`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`scr_`}),` followed by 64 hexadecimal characters`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Storage`}),_jsx(_components.td,{children:`Only a SHA-256 hash is stored; the plaintext is shown once`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Scope`}),_jsx(_components.td,{children:`One workspace; the key can read only that workspace’s jobs and captures`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Expiry`}),_jsx(_components.td,{children:`30 days after creation for keys generated in the dashboard`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Limit`}),_jsx(_components.td,{children:`Up to 10 active keys per workspace`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Status`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`ACTIVE`}),`, `,_jsx(_components.code,{children:`EXPIRED`}),`, or `,_jsx(_components.code,{children:`REVOKED`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Rate limits`}),_jsx(_components.td,{children:`Shared by the workspace owner’s account; extra keys do not add throughput or quota`})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`create-a-key`,children:`Create a key`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Open `,_jsx(_components.a,{href:`https://screenshotly.app/dashboard/tokens`,children:`Dashboard → API keys`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`In `,_jsx(_components.strong,{children:`Workspace`}),`, choose the personal or team workspace the key should belong to.`]}),`\n`,_jsxs(_components.li,{children:[`Enter a name that says where the key will live, such as `,_jsx(_components.code,{children:`production-api`}),` or\n`,_jsx(_components.code,{children:`github-actions`}),`. The name is optional; unnamed keys are called\n`,_jsx(_components.code,{children:`Default API Key`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Generate New Key`}),`, copy the key, and store it in your secret manager.\nIt is not shown again.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Each key in the list shows its status, creation date, expiry date, and the\nnumber of successful requests made with it.`}),`\n`,_jsx(Heading,{level:`2`,id:`store-keys-safely`,children:`Store keys safely`}),`\n`,_jsx(_components.p,{children:`Load the key from the environment or a secret manager at runtime:`}),`\n`,_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`Node.js`,numberOfLines:`2`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` apiKey`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` process`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`env`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`SCREENSHOTLY_API_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`apiKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`throw`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` Error`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'SCREENSHOTLY_API_KEY is not set'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Python`,numberOfLines:`5`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`api_key `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os.environ.get(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"SCREENSHOTLY_API_KEY\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` not`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` api_key:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` raise`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` RuntimeError`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"SCREENSHOTLY_API_KEY is not set\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})})]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Use a separate key for each environment and system: local development, CI,\nstaging, and production. Revoking one does not interrupt the others.`}),`\n`,_jsx(_components.li,{children:`Keep keys out of source control, client-side bundles, mobile apps, logs, and\nerror trackers.`}),`\n`,_jsxs(_components.li,{children:[`Give team members access through a `,_jsx(_components.a,{href:`/guides/teams-and-usage`,children:`team workspace`}),`\ninstead of sharing one personal key.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`rotate-a-key`,children:`Rotate a key`}),`\n`,_jsx(_components.p,{children:`Because dashboard keys expire after 30 days, plan rotation as a routine task:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Generate a new key in the same workspace.`}),`\n`,_jsx(_components.li,{children:`Update the secret in every system that uses the old key, and redeploy.`}),`\n`,_jsx(_components.li,{children:`Confirm traffic is flowing with the new key: its request count in the\ndashboard increases.`}),`\n`,_jsx(_components.li,{children:`Revoke the old key.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Set a reminder before the expiry date shown in the dashboard. When a key\nexpires, requests fail with `,_jsx(_components.code,{children:`401 Invalid API key`}),`. Handle `,_jsx(_components.code,{children:`401`}),` in your client\nby alerting a person rather than retrying, because retries cannot succeed.`]}),`\n`,_jsx(Heading,{level:`2`,id:`revoke-a-key`,children:`Revoke a key`}),`\n`,_jsxs(_components.p,{children:[`Click the delete icon next to a key in\n`,_jsx(_components.a,{href:`https://screenshotly.app/dashboard/tokens`,children:`Dashboard → API keys`}),`. Revocation\ntakes effect immediately and cannot be undone; the next request with that key\nreturns `,_jsx(_components.code,{children:`401`}),`.`]}),`\n`,_jsx(_components.p,{children:`A key can be revoked by the member who created it, or by an owner or admin of\nthe key’s workspace.`}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`If a key is exposed (committed to a repository, pasted into a ticket, or\nshipped in client code), revoke it first, then create a replacement. Do not\nwait for it to expire.`})}),`\n`,_jsx(Heading,{level:`2`,id:`troubleshooting`,children:`Troubleshooting`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Response`}),_jsx(_components.th,{children:`Meaning`}),_jsx(_components.th,{children:`What to do`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`401 Invalid API key`})}),_jsx(_components.td,{children:`The key is unknown, revoked, or expired.`}),_jsx(_components.td,{children:`Check the key’s status in the dashboard and rotate it.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`401 API key is required…`})}),_jsxs(_components.td,{children:[`No `,_jsx(_components.code,{children:`x-api-key`}),` or `,_jsx(_components.code,{children:`Authorization`}),` header was sent.`]}),_jsx(_components.td,{children:`Check that your client sets the header.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`403 Email verification required`})}),_jsx(_components.td,{children:`The workspace owner’s email address is not verified.`}),_jsx(_components.td,{children:`Verify the email address, then retry.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`”Failed to generate API key” in the dashboard`}),_jsx(_components.td,{children:`Often the workspace already has 10 active keys.`}),_jsx(_components.td,{children:`Revoke keys you no longer use, then try again.`})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`next-steps`,children:`Next steps`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/introduction/authentication#rate-limits`,children:`Authentication and rate limits`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/guides/security`,children:`Security`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/guides/teams-and-usage`,children:`Teams, usage, and retention`})}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Managing API keys","description":"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.","href":"/guides/managing-tokens"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Key facts","slug":"key-facts","depth":2,"children":[]},{"title":"Create a key","slug":"create-a-key","depth":2,"children":[]},{"title":"Store keys safely","slug":"store-keys-safely","depth":2,"children":[]},{"title":"Rotate a key","slug":"rotate-a-key","depth":2,"children":[]},{"title":"Revoke a key","slug":"revoke-a-key","depth":2,"children":[]},{"title":"Troubleshooting","slug":"troubleshooting","depth":2,"children":[]},{"title":"Next steps","slug":"next-steps","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"screenshotly","siteName":"Screenshotly","title":"Managing API keys - Screenshotly","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-14T17:43:53.518Z","originalFileLocation":"guides/managing-tokens.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Screenshotly\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/screenshotly/_generated/favicon/apple-touch-icon.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/screenshotly/_generated/favicon/favicon-32x32.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/screenshotly/_generated/favicon/favicon-16x16.png?v=3\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/screenshotly/_generated/favicon/favicon.ico?v=3\">\u003cmeta data-mint-head property=\"og:title\" content=\"Managing API keys - Screenshotly\">\u003cmeta data-mint-head property=\"og:description\" content=\"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Screenshotly\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.screenshotly.app/guides/managing-tokens\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://screenshotly.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Managing+API+keys\u0026amp;description=Create%2C+scope%2C+rotate%2C+and+revoke+Screenshotly+API+keys+in+the+dashboard%2C+with+key+expiry%2C+per-workspace+limits%2C+and+a+zero-downtime+rotation+checklist.\u0026amp;theme=6eed92d095d6b7990c19fe34\u0026amp;signature=fd1ad2ab92098883dd5d750467ab61440ae4fd263d767e3fbaa5699d7f969756\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Managing API keys - Screenshotly\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://screenshotly.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Managing+API+keys\u0026amp;description=Create%2C+scope%2C+rotate%2C+and+revoke+Screenshotly+API+keys+in+the+dashboard%2C+with+key+expiry%2C+per-workspace+limits%2C+and+a+zero-downtime+rotation+checklist.\u0026amp;theme=6eed92d095d6b7990c19fe34\u0026amp;signature=fd1ad2ab92098883dd5d750467ab61440ae4fd263d767e3fbaa5699d7f969756\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/screenshotly/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Screenshotly\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#2563eb\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.screenshotly.app/guides/managing-tokens\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/guides/managing-tokens.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.screenshotly.app/#organization\",\"name\":\"Screenshotly\",\"url\":\"https://docs.screenshotly.app\"},{\"@type\":\"WebSite\",\"@id\":\"https://docs.screenshotly.app#website\",\"name\":\"Screenshotly\",\"url\":\"https://docs.screenshotly.app\",\"publisher\":{\"@id\":\"https://docs.screenshotly.app/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.screenshotly.app/guides/managing-tokens#webpage\",\"url\":\"https://docs.screenshotly.app/guides/managing-tokens\",\"name\":\"Managing API keys\",\"description\":\"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.\",\"dateModified\":\"2026-11-14T17:43:53.518Z\",\"isPartOf\":{\"@id\":\"https://docs.screenshotly.app#website\"},\"breadcrumb\":{\"@id\":\"https://docs.screenshotly.app/guides/managing-tokens#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.screenshotly.app/guides/managing-tokens#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Guides\",\"item\":\"https://docs.screenshotly.app/guides/capturing-screenshots\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Managing API keys\",\"item\":\"https://docs.screenshotly.app/guides/managing-tokens\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.screenshotly.app/guides/managing-tokens#article\",\"headline\":\"Managing API keys\",\"name\":\"Managing API keys\",\"description\":\"Create, scope, rotate, and revoke Screenshotly API keys in the dashboard, with key expiry, per-workspace limits, and a zero-downtime rotation checklist.\",\"url\":\"https://docs.screenshotly.app/guides/managing-tokens\",\"mainEntityOfPage\":{\"@id\":\"https://docs.screenshotly.app/guides/managing-tokens#webpage\"},\"dateModified\":\"2026-11-14T17:43:53.518Z\",\"publisher\":{\"@id\":\"https://docs.screenshotly.app/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.screenshotly.app#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Screenshotly\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Screenshotly\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/guides/managing-tokens.md","siteName":"Screenshotly","nav":{"global":null,"groups":[{"group":"Getting Started","pages":[{"title":"Welcome","href":"/introduction/welcome"},{"title":"Quickstart","href":"/introduction/quickstart"},{"title":"Authentication","href":"/introduction/authentication"}]},{"group":"API Reference","pages":[{"title":"Synchronous capture","api":"POST /api/screenshot","href":"/api/screenshots"},{"title":"Async and batch jobs","href":"/api/async-jobs"}]},{"group":"Guides","pages":[{"title":"Capturing screenshots","href":"/guides/capturing-screenshots"},{"title":"Using mockups","href":"/guides/using-mockups"},{"title":"Webhooks","description":"Receive Screenshotly capture results by webhook: events, payloads, headers, retry schedule, and how to verify the X-Screenshotly-Signature HMAC-SHA256 signature.","href":"/guides/webhooks"},{"title":"Managing API keys","href":"/guides/managing-tokens"},{"title":"Security","description":"How Screenshotly protects API keys, blocks private-network targets, encrypts queued payloads, signs downloads and webhooks, and deletes captures.","href":"/guides/security"},{"title":"Teams, usage, and retention","href":"/guides/teams-and-usage"}]}]},"basePath":"","title":"Managing API keys - Screenshotly","buildId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","deploymentId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","dynamics":[],"chunks":[]}