> ## Documentation Index
> Fetch the complete documentation index at: https://docs.byzantine.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# API authentication

> Authentication for the Byzantine API.

All API requests must be authenticated using ECDSA signature-based authentication. You'll use your **Integrator Private Key** to sign each request and include the signature in the request headers.

### Authentication Headers

Each API request requires the following headers:

| Header         | Description                                                                 |
| -------------- | --------------------------------------------------------------------------- |
| `X-Pubkey`     | Your public key derived from your private key (hex format with `0x` prefix) |
| `X-Timestamp`  | Current Unix timestamp in seconds                                           |
| `X-Signature`  | ECDSA signature of the request (DER-encoded hex with `0x` prefix)           |
| `Content-Type` | Must be `application/json`                                                  |

<Tabs>
  <Tab title="Use our Integrator SDK">
    Our Integrator SDK provides a convenient way to generate the authentication headers for your API requests.

    The `getStamp` method returns an object containing the required authentication headers (`X-Pubkey`, `X-Timestamp`, `X-Signature`, and `Content-Type`) that you can include in your API request.

    #### Installation

    ```bash theme={null}
    npm install @byzantine/integrator-sdk
    ```

    #### Initialize the Byzantine Client

    ```typescript theme={null}
    import { ByzantineClient } from '@byzantine/integrator-sdk';

    const client = new ByzantineClient({
      integratorPrivateKey: 'YOUR_INTEGRATOR_PRIVATE_KEY',
    });
    ```

    #### Usage example

    Use the `getStamp` method to generate authentication headers for your API requests:

    ```typescript theme={null}
    const payload = {
      // Your request payload
    };

    // Generate the api key stamp
    const apiKeyStamp = await client.apiKey.getStamp(
      "POST",
      "/v1/submit/send-transaction-otp",
      payload
    );

    // Use the apiKeyStamp headers in your API call
    const response = await fetch(
      "https://api.byzantine.fi/v1/submit/send-transaction-otp?chain_id=1",
      {
        method: "POST",
        headers: apiKeyStamp,
        body: payload,
      }
    );
    ```
  </Tab>

  <Tab title="Manual implementation">
    #### Signature Generation

    The signature is generated by:

    1. Constructing a message string in the format: `{timestamp}{method}{path_and_query}{body}`

    * **timestamp**: Unix timestamp in seconds
    * **method**: HTTP method in uppercase (e.g., `GET`, `POST`)
    * **path\_and\_query**: Full path including query parameters (e.g., `/query/get-deposit?chain_id=1`)
    * **body**: JSON stringified request body (empty string for GET requests)

    2. Hashing the message using SHA-256
    3. Signing the hash with your private key using ECDSA (secp256k1 curve)
    4. Encoding the signature in DER format and converting to hex

    #### Implementation Example

    Here's a reference implementation in Node.js:

    ```javascript theme={null}
    import elliptic from "elliptic";
    import { createHash } from "crypto";

    const EC = elliptic.ec;
    const ec = new EC("p256");

    const INTEGRATOR_PRIVATE_KEY = process.env.INTEGRATOR_PRIVATE_KEY;

    export function generateHeaders(method, pathAndQuery, body = "") {
      // Get the key pair
      const cleanPrivateKey = INTEGRATOR_PRIVATE_KEY.replace(/^0x/, "");
      const keyPair = ec.keyFromPrivate(cleanPrivateKey, "hex");
      const publicKey = "0x" + keyPair.getPublic(true, "hex");

      // Get the timestamp in seconds since the Unix epoch (UTC)
      const timestamp = Math.floor(Date.now() / 1000).toString();

      // Build the message to sign
      // Format: {timestamp}{method}{path_and_query}{body}
      const bodyStr = typeof body === "object" ? JSON.stringify(body) : body;
      const message = `${timestamp}${method.toUpperCase()}${pathAndQuery}${bodyStr}`;

      // Hash the message and sign it
      const messageHash = createHash("sha256").update(message).digest();
      const signature = keyPair.sign(messageHash);

      // Encode the signature in DER then in hex
      const signatureHex = "0x" + signature.toDER("hex");

      return {
        "X-Pubkey": publicKey,
        "X-Timestamp": timestamp,
        "X-Signature": signatureHex,
        "Content-Type": "application/json",
      };
    }
    ```

    #### Usage Example

    ```javascript theme={null}
    // Example POST request
    const body = {
      userId: "user123",
      vaultAddress: "0x...",
    };
    const headers = generateHeaders("POST", "/submit/deposit", body);

    // Make the API call
    const response = await fetch("https://api.byzantine.fi/submit/deposit", {
      method: "POST",
      headers: headers,
      body: JSON.stringify(body),
    });
    ```
  </Tab>
</Tabs>

<Warning>**Keep your Integrator Private Key secure!**</Warning>

## Managing your integrator keys

You can manage your integrator credentials programmatically - there's no need to contact us to rotate or scope a key. Each credential is an ECDSA keypair with an access scope:

* **`read_write`** - full access, including mutations and key management.
* **`read_only`** - restricted to read/query endpoints.

| Action                                                    | Endpoint                                                                                                                          |
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Inspect the current credential's id, scope & capabilities | [`GET /v1/integrator/whoami`](/api-reference/integrator-key-management/get-current-integrator-credential-capabilities)            |
| Issue a new credential                                    | [`POST /v1/integrator/credentials`](/api-reference/integrator-key-management/issue-a-credential-for-the-authenticated-integrator) |
| Update a credential's label, scope, or active status      | [`PATCH /v1/integrator/credentials/{pubkey}`](/api-reference/integrator-key-management/update-a-credential)                       |
| Delete a credential                                       | [`DELETE /v1/integrator/credentials/{pubkey}`](/api-reference/integrator-key-management/delete-an-integrator-credential)          |

You can call these endpoints directly, or use the [Byzantine SDK](/api-reference/byzantine-sdk)'s typed method wrappers to manage your keys without building the requests by hand.

<Note>
  Managing keys requires a `read_write` credential, and a credential can't deactivate, rescope, or delete **itself**, so you always keep at least one working read-write key.
</Note>

## OpenAPI Specification

Explore the full structure and generate your own client using our [OpenAPI specification](http://docs.byzantine.fi/api-reference/openapi-integrator.json).
