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

# API Keys

> Create, list, and revoke API keys. Include your key in the Authorization header as a Bearer token.

Vinci uses API keys for authentication. Include your key in every request.

```http title="HTTP Header" theme={"system"}
Authorization: Bearer sk-your-api-key-here
```

<Warning>
  Keep your API keys secure and never expose them in client-side code. Use environment variables or a secret manager.
</Warning>

## Get your first API key

The easiest way to get started is by creating your first API key through the [Vinci Dashboard](https://app.tryvinci.com/dashboard/api).

1. Sign in to your [Vinci account](https://app.tryvinci.com)
2. Navigate to the [API Keys page](https://app.tryvinci.com/dashboard/api)
3. Click "Create New API Key"
4. Give your key a descriptive name (e.g., "Development", "Production")
5. Copy and securely store your API key

<Tip>
  Your API key will only be shown once. Make sure to copy it immediately and store it securely.
</Tip>

## Create API key

```http title="Endpoint" theme={"system"}
POST /api/v1/keys
```

```http title="Authentication" theme={"system"}
Authorization: Bearer sk-existing-api-key
```

```json title="Response" theme={"system"}
{
  "key_id": "vinci_abc123...",
  "name": "Production API Key",
  "api_key": "sk-your-new-api-key-here",
  "rate_limit": 10,
  "created_at": "2024-01-01T00:00:00Z"
}
```

<CodeGroup>
  ```curl cURL theme={"system"}
  curl -X POST "https://tryvinci.com/api/v1/keys" \
    -H "Authorization: Bearer sk-existing-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Production API Key",
      "rate_limit": 20
    }'
  ```

  ```python create_key.py theme={"system"}
  import requests

  url = "https://tryvinci.com/api/v1/keys"
  headers = {
    "Authorization": "Bearer sk-existing-api-key",
    "Content-Type": "application/json",
  }
  data = { "name": "Production API Key", "rate_limit": 20 }

  resp = requests.post(url, headers=headers, json=data)
  resp.raise_for_status()
  result = resp.json()
  print(f"New API key: {result['api_key']}")
  print(f"Key ID: {result['key_id']}")
  ```

  ```javascript create_key.js theme={"system"}
  const response = await fetch("https://tryvinci.com/api/v1/keys", {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk-existing-api-key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ name: "Production API Key", rate_limit: 20 }),
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const result = await response.json();
  console.log(`New API key: ${result.api_key}`);
  console.log(`Key ID: ${result.key_id}`);
  ```
</CodeGroup>

Tip
Store the full API key securely as it will not be shown again.

## List API keys

```http title="Endpoint" theme={"system"}
GET /api/v1/keys
```

```http title="Authentication" theme={"system"}
Authorization: Bearer sk-your-api-key-here
```

```json title="Response" theme={"system"}
{
  "api_keys": [
    {
      "key_id": "vinci_abc123...",
      "name": "Production API Key",
      "is_active": true,
      "created_at": "2024-01-01T00:00:00Z",
      "last_used": "2024-01-01T12:00:00Z",
      "key_preview": "sk-...abc123...",
      "rate_limit": 10
    }
  ],
  "count": 1
}
```

<CodeGroup>
  ```curl cURL theme={"system"}
  curl -X GET "https://tryvinci.com/api/v1/keys" \
    -H "Authorization: Bearer sk-your-api-key-here"
  ```

  ```python list_keys.py theme={"system"}
  import requests

  url = "https://tryvinci.com/api/v1/keys"
  headers = { "Authorization": "Bearer sk-your-api-key-here" }

  resp = requests.get(url, headers=headers)
  resp.raise_for_status()
  result = resp.json()

  print(f"Total API keys: {result['count']}")
  for key in result["api_keys"]:
    status = "Active" if key["is_active"] else "Disabled"
    print(f"- {key['name']}: {key['key_preview']} ({status})")
  ```

  ```javascript list_keys.js theme={"system"}
  const response = await fetch("https://tryvinci.com/api/v1/keys", {
    headers: { "Authorization": "Bearer sk-your-api-key-here" },
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const result = await response.json();
  console.log(`Total API keys: ${result.count}`);
  result.api_keys.forEach((key) => {
    const status = key.is_active ? "Active" : "Disabled";
    console.log(`- ${key.name}: ${key.key_preview} (${status})`);
  });
  ```
</CodeGroup>

## Revoke API key

```http title="Endpoint" theme={"system"}
DELETE /api/v1/keys/{key_id}
```

```http title="Authentication" theme={"system"}
Authorization: Bearer sk-your-api-key-here
```

```json title="Response" theme={"system"}
{
  "message": "API key revoked successfully",
  "key_id": "vinci_abc123..."
}
```

<CodeGroup>
  ```curl cURL theme={"system"}
  curl -X DELETE "https://tryvinci.com/api/v1/keys/vinci_abc123..." \
    -H "Authorization: Bearer sk-your-api-key-here"
  ```

  ```python revoke_key.py theme={"system"}
  import requests

  key_id = "vinci_abc123..."
  url = f"https://tryvinci.com/api/v1/keys/{key_id}"
  headers = { "Authorization": "Bearer sk-your-api-key-here" }

  resp = requests.delete(url, headers=headers)
  resp.raise_for_status()
  print(resp.json()["message"])
  ```

  ```javascript revoke_key.js theme={"system"}
  const keyId = "vinci_abc123...";
  const response = await fetch(`https://tryvinci.com/api/v1/keys/${keyId}`, {
    method: "DELETE",
    headers: { "Authorization": "Bearer sk-your-api-key-here" },
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const result = await response.json();
  console.log(result.message);
  ```
</CodeGroup>

## Rate limits

Default: 10 requests/min. Max: 100 requests/min.

```http title="Rate limit headers" theme={"system"}
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1640995200
```

<CodeGroup>
  ```python rate_limit_handling.py theme={"system"}
  import time, requests

  def get_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
      r = requests.get(url, headers=headers)
      if r.status_code == 429:
        time.sleep(60)
        continue
      r.raise_for_status()
      return r
    raise RuntimeError("Max retries exceeded")
  ```

  ```javascript rate_limit_handling.js theme={"system"}
  async function getWithRetry(url, options = {}, maxRetries = 3) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const r = await fetch(url, options);
      if (r.status === 429) {
        await new Promise((res) => setTimeout(res, 60_000));
        continue;
      }
      if (!r.ok) throw new Error(`HTTP ${r.status}`);
      return r;
    }
    throw new Error("Max retries exceeded");
  }
  ```
</CodeGroup>

## Best practices

* Rotate keys regularly.
* Use different keys per environment.
* Monitor last\_used to identify stale keys.
