> ## Documentation Index
> Fetch the complete documentation index at: https://sigil-10dddbf2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Issue your first Sigil and gate an API endpoint in minutes.

This guide walks through the two core flows: issuing a credential to an agent, and protecting an API endpoint so only credentialed agents can call it.

## Issue a Sigil

A principal calls `issueSigil` to create an on-chain credential for an agent keypair. The principal's wallet signs and pays for rent.

```ts theme={null}
import { SigilClient } from '@sigil-xyz/sdk'
import { PublicKey } from '@solana/web3.js'
import BN from 'bn.js'

const client = new SigilClient({ connection, wallet: principalWallet })

const txSig = await client.issueSigil({
  agent: new PublicKey('AgentPublicKeyHere...'),
  capabilities: [
    {
      category: 'image-generation',
      allowedDomains: ['api.openai.com', 'api.stability.ai'],
    },
  ],
  spendLimits: {
    perTx:  new BN(100_000),    // 0.1 USDC per request
    perDay: new BN(5_000_000),  // 5 USDC daily cap
  },
  expiresAt: Math.floor(Date.now() / 1000) + 86_400 * 30, // 30 days
})
```

<Note>
  Spend amounts are in micro-USDC (6 decimal places). `1_000_000` = 1 USDC.
</Note>

Fetch the credential right after to confirm it's on-chain:

```ts theme={null}
const sigil = await client.getSigil(agentPublicKey, principalWallet.publicKey)
console.log(sigil.capabilities, sigil.spendLimitPerTx.toString())
```

## Gate an API endpoint

Add the middleware to your server. It verifies the agent's signature, checks the on-chain Sigil, and records the spend — returning `402` if anything fails.

<Tabs>
  <Tab title="Express">
    ```ts theme={null}
    import express from 'express'
    import { createSigilMiddleware } from '@sigil-xyz/x402'
    import BN from 'bn.js'

    const app = express()

    app.post(
      '/api/generate',
      createSigilMiddleware({
        connection,
        serverWallet,
        requiredCapability: 'image-generation',
        spendAmount: new BN(50_000), // 0.05 USDC per request
      }),
      (req, res) => {
        // req.sigilAgent → verified agent pubkey (base58)
        res.json({ result: 'generated' })
      }
    )
    ```
  </Tab>

  <Tab title="Next.js App Router">
    ```ts theme={null}
    // app/api/generate/route.ts
    import { withSigilAuth } from '@sigil-xyz/x402/next'
    import { NextResponse } from 'next/server'
    import BN from 'bn.js'

    export const POST = withSigilAuth(
      async (req) => {
        // req.sigilAgent → verified agent pubkey (base58)
        return NextResponse.json({ result: 'generated' })
      },
      {
        connection,
        serverWallet,
        requiredCapability: 'image-generation',
        spendAmount: new BN(50_000),
      }
    )
    ```
  </Tab>
</Tabs>

## Call the protected endpoint from an agent

The agent signs each request using `buildSigilHeaders` and attaches the result as HTTP headers.

```ts theme={null}
import { buildSigilHeaders } from '@sigil-xyz/x402'
import { Keypair } from '@solana/web3.js'
import BN from 'bn.js'

const agentKeypair = Keypair.fromSecretKey(/* agent's secret key */)

const headers = buildSigilHeaders({
  agentKeypair,
  method: 'POST',
  path: '/api/generate',
  spendAmount: new BN(50_000),
})

const response = await fetch('https://api.example.com/api/generate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    ...headers,
  },
  body: JSON.stringify({ prompt: 'a red fox' }),
})
```

If the Sigil is invalid, revoked, expired, or missing the required capability, the server returns `402 Payment Required`:

```json theme={null}
{
  "protocol": "sigil-v1",
  "message": "Agent Sigil is invalid or lacks the 'image-generation' capability",
  "requiredCapability": "image-generation",
  "spendAmount": "50000",
  "credentialProgram": "ZFK63KBXDhGCYm5orVo5QiTBaBhWD4PUcUDBG6fjTkH",
  "network": "devnet",
  "docs": "https://docs.sigil.xyz/x402"
}
```
