> For the complete documentation index, see [llms.txt](https://docs.opinion.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opinion.trade/developer-guide/opinion-open-api/authentication.md).

# Authentication

Public data endpoints do not require an API key. Authenticated endpoints require providing your API key in the `apikey` HTTP request header. The same key works for Opinion OpenAPI, Opinion Websocket, and Opinion CLOB SDK.

#### Getting an API key

You can create your own API key instantly by signing an EIP-712 message with your wallet — no application form or approval needed.

Prerequisites:

* Your wallet must be a registered Opinion account with a trading wallet enabled — connect the wallet on [opinion.trade](https://opinion.trade) and complete onboarding first.
* Each wallet holds one active API key at a time.

The three Auth endpoints (`POST` / `GET` / `DELETE` `/auth/api-key`) are authenticated by wallet signature only — no API key required. Every request carries three headers: `OPINION_ADDRESS` (the signing wallet address), `OPINION_SIGNATURE` (EIP-712 signature) and `OPINION_TIMESTAMP` (Unix timestamp in seconds, must match the signed `timestamp` field).

#### Signing the request

Sign the following EIP-712 typed data with your wallet's private key:

```json
{
  "types": {
    "EIP712Domain": [
      { "name": "name", "type": "string" },
      { "name": "version", "type": "string" },
      { "name": "chainId", "type": "uint256" }
    ],
    "OpinionApiKeyAuth": [
      { "name": "walletAddress", "type": "address" },
      { "name": "action", "type": "string" },
      { "name": "timestamp", "type": "string" }
    ]
  },
  "primaryType": "OpinionApiKeyAuth",
  "domain": {
    "name": "Opinion OpenAPI",
    "version": "1",
    "chainId": 56
  },
  "message": {
    "walletAddress": "0xYourWalletAddress",
    "action": "create",
    "timestamp": "1753690000"
  }
}
```

* `action` must match the endpoint: `create` for POST, `get` for GET, `delete` for DELETE. A signature for one action cannot be reused for another.
* Signatures expire after 5 minutes. `create` and `delete` signatures are single-use — sign a fresh message for each attempt. `get` signatures can be retried within the window.

#### Example

```typescript
import { Wallet } from "ethers";

const wallet = new Wallet(process.env.PRIVATE_KEY);
const timestamp = Math.floor(Date.now() / 1000).toString();

const signature = await wallet.signTypedData(
  { name: "Opinion OpenAPI", version: "1", chainId: 56 },
  {
    OpinionApiKeyAuth: [
      { name: "walletAddress", type: "address" },
      { name: "action", type: "string" },
      { name: "timestamp", type: "string" },
    ],
  },
  { walletAddress: wallet.address, action: "create", timestamp }
);

const res = await fetch("https://openapi.opinion.trade/openapi/auth/api-key", {
  method: "POST",
  headers: {
    OPINION_ADDRESS: wallet.address,
    OPINION_SIGNATURE: signature,
    OPINION_TIMESTAMP: timestamp,
  },
});
console.log(await res.json());
// { "errno": 0, "errmsg": "", "result": { "apiKey": "…", "walletAddress": "0x…" } }
```

#### Response codes

Unlike the data endpoints, the Auth endpoints return HTTP `200` with the outcome in an `errno` / `errmsg` / `result` envelope — always check `errno`:

| errno   | Meaning                                                                        |
| ------- | ------------------------------------------------------------------------------ |
| `0`     | Success                                                                        |
| `11004` | Self-service key issuance is temporarily disabled                              |
| `11005` | Wallet is not a registered Opinion account — connect it on opinion.trade first |
| `11009` | API key already exists — use GET to retrieve it                                |
| `11010` | No API key found for this wallet                                               |
| `11011` | Invalid signature                                                              |
| `11012` | Signature expired                                                              |
| `11013` | Signature already used — sign a fresh message                                  |

#### Key activation timing

* A newly created key becomes active at the gateway within about **15 seconds**. If your first requests return `401`, simply retry — no backoff needed.
* After `DELETE`, the old key stops working within about 10 seconds.
* To rotate a key, call `DELETE` then `POST`, and plan for up to \~15 seconds during which neither key is usable.

If you lose your key, call `GET` at any time to retrieve it. If your key is compromised, `DELETE` it and create a new one.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.opinion.trade/developer-guide/opinion-open-api/authentication.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
