> ## Documentation index
> Fetch the complete documentation index at: https://docs.predictefy.com/llms.txt
> Use it to discover every available page before exploring further.

# API keys

> Create, show, regenerate, and revoke Predictefy API keys, including the limits the console enforces when it shows a key again.

Every request is authenticated with an account API key. Keys are created and managed in the
[developer dashboard](https://portal.predictefy.com/keys); the API itself never mints one.

## Create a key

1. Sign in at [portal.predictefy.com](https://portal.predictefy.com). Signing in never creates
   a key automatically.
2. Open **API keys**, choose **Create API key**, and give it a name. The name is how the list
   identifies it later, alongside the key prefix.
3. Copy the `pk_live_…` value from the dialog.

New keys carry the `read` scope only. Select the trading opt-in when creating the key to add
`trade`; existing keys are never changed. The `sql` scope that `POST /v1/sql` requires is not
granted by any self-serve plan — [contact support](mailto:support@predictefy.com) for it.

How many keys an account can hold at once is set by its plan (see the
[plan table](/guides/credits/#public-plans)). The limit counts keys that are not revoked and is
enforced in the database, so a creation refused at the cap keeps being refused: revoke a key you
no longer use, or move to a plan with a higher limit.

## Show a key again

Only a hash of the key authenticates requests. The console additionally keeps an encrypted copy
so the API keys page can show the full value again: press the eye control on a key's row, and
the row hides it again after a minute. The copy button copies the full key whenever the key can
be shown.

The server checks every attempt and enforces these rules:

- **Personal keys of the signed-in account only.** Organization keys are shown once when they
  are minted, on the organization screen.
- **Any age, any number of times.** There is no expiry on showing a key and no per-key cap.
- **Ten attempts per account per rolling hour, refusals included.** Past that, attempts are
  refused for the rest of the hour with "Too many attempts; try again in an hour".
- **Revoked keys are never shown.** Revoking erases the encrypted copy in the same statement.
- **Keys minted before the feature shipped cannot be shown.** The console says so on the row and
  offers **Regenerate** instead.

Every attempt, allowed or refused, is recorded in the account's audit log with the client IP
address and browser user agent before any key text is returned. If that record cannot be
written, nothing is returned.

:::caution[Showing a key again is a convenience, not a recovery path]
The encrypted copy can only be decrypted by the Predictefy web servers that hold the encryption
secret, so a copy of the database on its own exposes no key. It is still the same secret you
already hold: if a key may have been exposed, regenerate or revoke it instead of retrieving it.
:::

## Regenerate a key

**Regenerate** revokes the current key and mints a replacement with the same name in one
transaction, then shows the new value once. Use it when a key may have leaked, or when an older
key can no longer be shown.

The replacement is a different key: update every client that used the old value.

## Revoke a key

**Revoke** stops the key authenticating and erases its stored encrypted copy. Services pick the
revocation up within seconds, and the key cannot be shown or restored afterwards. If a key may
have been exposed, revoke or regenerate it before anything else, and never send a key in a
support message.

## Handling keys

- Send the key in the `Authorization: Bearer pk_live_…` header. Never put it in a query string:
  query strings are recorded in request logs along the way.
- Keep keys in environment variables or a secret manager, not in source control or a browser.
- Use one key per application or environment, so revoking one does not stop everything else.

The response envelope that reports an unauthenticated or unauthorized request is described in
[Errors](/guides/errors/).
