> For the complete documentation index, see [llms.txt](https://docs.goassay.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.goassay.ai/developers/list-your-api-get-started/api-key-or-signature.md).

# API key or signature

Choose how your API checks that a request comes from Assay.

Your API needs to reject calls that bypass Assay. Start with an API key if your service already checks one. Use an Assay signature when you also want to detect changed requests and repeated signed calls.

## How it works

With an **API key**, Assay sends the secret headers you store in the app. Your endpoint checks their values before serving the request. Anyone who gets the key can use it, so keep it secret and use HTTPS.

With an **Assay signature (recommended)**, your endpoint verifies an Ed25519 signature using Assay's public keys. There is no shared API key to store. The signature covers the method, host, path, query, call ID and, when present, a SHA-256 digest of the body. A digest is a fingerprint of the exact body bytes.

| Choose                            | What your endpoint must enforce                                    | Protection and limits                                                                                                                                                                      |
| --------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **API key**                       | Require your secret header values.                                 | Rejects callers without the key. The key alone does not bind a call to its body or prevent replay.                                                                                         |
| **Assay signature (recommended)** | Verify the signature, body digest, time window and one-time nonce. | Rejects forged or changed signed requests. A nonce identifies a signed request so a replay store can reject a repeat. Replay protection works only across instances that share that store. |
| **Both**                          | Require both checks to pass.                                       | Keeps your existing key check and adds signature verification.                                                                                                                             |
| **Neither**                       | No authentication check.                                           | Anyone who learns the endpoint address can call it directly, without paying through Assay.                                                                                                 |

Assay signs normal provider calls in every mode. It also attaches stored credential headers for the destination origin, even if you change the mode to signature. Choosing a mode does not install a check in your API or remove stored keys.

## Set up an API key

Use this path when your API already rejects calls without a key. In your listing's **Connect & test** step, choose **API key**, then **Add headers**. [List a catalogue tool](https://docs.goassay.ai/list-your-api/list-a-catalogue-tool) shows each screen. What matters for your API:

* Put the key in a header, not in the address. For a bearer token, use `Authorization` with the complete value `Bearer YOUR_KEY`.
* Headers are stored for the listing's origin: the address's scheme, host and port. A different origin needs its own set.
* Values are encrypted and never shown in full again. Saving replaces the complete header set, so include every header your API needs.

## Check it worked

The normal call should pass. The tester also tries a call without your key. Fix **API key not enforced** if it appears: your endpoint accepted that call.

## Choose signature verification instead

Use a gateway in front of your API or add the verifier inside your service. In **Connect & test → Authentication**, select **Assay signature (recommended)**, or **Both** if your API must also require a key. There is no default selection. Finish installing the verifier before running the test; selecting the mode alone does not protect the endpoint.

## Errors

| Symptom                                   | Fix                                                                                                |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------- |
| The test asks for API key headers.        | Save the connection, then add headers for the saved address. A different origin needs its own set. |
| Your API returns an authentication error. | Check the header name and full value against what your API reads.                                  |
| **Signature not enforced**                | Ensure the signature verifier covers the route Assay calls and cannot be bypassed.                 |

## Go further

* List your API (optional): [Or: publish your own API](https://docs.goassay.ai/list-your-api/publish-your-own-api).

## Next

* [Verify with a Cloudflare Worker (no code)](/developers/list-your-api-get-started/cloudflare-worker.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.goassay.ai/developers/list-your-api-get-started/api-key-or-signature.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
