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

# Agent tokens

> Verify and manage Gate agent tokens in your API. Validate agt_ tokens with one HTTP call to Gate, cache results, and handle expiry and revocation.

Gate issues an `agt_` agent token for every successful signup. Developers include this token in API calls to your service. Verify it with a single HTTP call to Gate.

## Verify a token

<CodeGroup>
  ```javascript Node.js theme={"dark"}
  app.use(async (req, res, next) => {
    const token = req.headers.authorization?.replace('Bearer ', '');

    if (token?.startsWith('agt_')) {
      const resp = await fetch('https://api.usefoil.com/gate/agent-tokens/verify', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${process.env.FOIL_SECRET_KEY}`,
        },
        body: JSON.stringify({ token }),
      });
      const { data } = await resp.json();

      if (!data.valid) return res.status(401).json({ error: 'Invalid token' });
      req.gateAccountId = data.gate_account_id;
    }

    next();
  });
  ```

  ```python Python theme={"dark"}
  import requests

  def verify_agent_token(token: str) -> dict | None:
      resp = requests.post(
          "https://api.usefoil.com/gate/agent-tokens/verify",
          headers={
              "Authorization": f"Bearer {os.environ['FOIL_SECRET_KEY']}",
              "Content-Type": "application/json",
          },
          json={"token": token},
      )
      data = resp.json().get("data", {})
      return data if data.get("valid") else None
  ```

  ```go Go theme={"dark"}
  func verifyAgentToken(token string) (*AgentTokenInfo, error) {
      body, _ := json.Marshal(map[string]string{"token": token})
      req, _ := http.NewRequest("POST",
          "https://api.usefoil.com/gate/agent-tokens/verify",
          bytes.NewReader(body))
      req.Header.Set("Authorization", "Bearer "+os.Getenv("FOIL_SECRET_KEY"))
      req.Header.Set("Content-Type", "application/json")

      resp, err := http.DefaultClient.Do(req)
      // ... parse response
  }
  ```

  ```ruby Ruby theme={"dark"}
  require 'net/http'
  require 'json'

  def verify_agent_token(token)
    uri = URI('https://api.usefoil.com/gate/agent-tokens/verify')
    req = Net::HTTP::Post.new(uri, {
      'Authorization' => "Bearer #{ENV['FOIL_SECRET_KEY']}",
      'Content-Type' => 'application/json',
    })
    req.body = { token: token }.to_json
    res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
    JSON.parse(res.body).dig('data')
  end
  ```

  ```php PHP theme={"dark"}
  function verifyAgentToken(string $token): ?array {
      $ch = curl_init('https://api.usefoil.com/gate/agent-tokens/verify');
      curl_setopt_array($ch, [
          CURLOPT_POST => true,
          CURLOPT_HTTPHEADER => [
              'Authorization: Bearer ' . getenv('FOIL_SECRET_KEY'),
              'Content-Type: application/json',
          ],
          CURLOPT_POSTFIELDS => json_encode(['token' => $token]),
          CURLOPT_RETURNTRANSFER => true,
      ]);
      $data = json_decode(curl_exec($ch), true)['data'] ?? [];
      return ($data['valid'] ?? false) ? $data : null;
  }
  ```

  ```bash cURL theme={"dark"}
  curl -X POST https://api.usefoil.com/gate/agent-tokens/verify \
    -H "Authorization: Bearer sk_live_..." \
    -H "Content-Type: application/json" \
    -d '{"token": "agt_..."}'
  ```
</CodeGroup>

## Verification response

```json theme={"dark"}
{
  "data": {
    "valid": true,
    "gate_account_id": "gacct_...",
    "status": "active",
    "created_at": "2026-04-01T..."
  }
}
```

Invalid or revoked tokens return `{ "data": { "valid": false } }`.

## Caching

The verify endpoint returns `Cache-Control: max-age=60`. Cache results to avoid hitting Gate on every request.

## Token lifecycle

* **Issued**: on every successful signup via Gate
* **Expires**: 90 days after last use (rolling expiry)
* **Revoked**: via `POST /gate/agent-tokens/revoke` or from the dashboard

## What's next

* [Webhook implementation](/gate/webhook) — handle signup events
* [Dashboard login](/gate/dashboard-login) — magic link authentication
