# Vectorway API Reference

Machine-readable, agent-friendly version of the public Vectorway API. Single source of truth for every endpoint shown on https://vectorway.io/docs.

- Base URL: `https://api.vectorway.io`
- Site: https://vectorway.io
- OpenAPI spec: https://vectorway.io/openapi.json
- Last generated: 2026-06-07T03:54:53.149Z

## Authentication

Three auth modes, listed in the order most agents will encounter them:

- **x402** — header `X-PAYMENT: <base64 signed USDC payment>`. No api key, no account, no onboarding; the buyer wallet is taken from the signed payment. Used on `POST /v1/chat/completions` (pay-per-call), `POST /v1/auth/agent-onboard`, and `POST /v1/credits/purchase`.
- **API key** — header `x-api-key: vw_<KEY_ID>_<SECRET>`. Debits credits from the wallet that owns the key (created via SIWE or `/v1/auth/agent-onboard`). Used on the credits-based chat path and all memory endpoints.
- **JWT (SIWE)** — header `Authorization: Bearer <ACCESS_JWT>`. Obtain by signing `/v1/auth/siwe/challenge` and POSTing to `/v1/auth/siwe/verify`. Used for control plane: account, billing, api key management.

> **Dual-auth shortcut.** `POST /v1/chat/completions` accepts *either* a per-call x402 `X-PAYMENT` *or* an `x-api-key` on the same URL — the server picks the path based on which header is present. Both paths price the same per-token math; only the unit differs (USDC on x402, credits on api-key). Streaming (`stream:true`) is api-key-only — x402 requests with `stream:true` return 400.

## Errors

- `400` — unsupported combination (e.g. `stream:true` on x402) or malformed request body
- `401` — invalid or missing auth
- `402` — payment required or credits exhausted
- `403` — wallet mismatch (api key / JWT does not own the target wallet)
- `404` — resource not found / wrong owner
- `409` — idempotency conflict
- `422` — request body validation failure
- `429` — rate limited (wallet-scoped quotas; separate buckets for control-plane vs runtime)
- `5xx` — upstream gateway error

---

## Inference

The one endpoint most agents need. Per-token billing — pay-per-call with x402, or use an API key that debits credits from a pre-funded balance.

### `POST /v1/chat/completions`

**Chat completions — billed per token.**

OpenAI-style LLM completions with optional wallet-scoped vector memory. Pay per call via X-PAYMENT (x402 USDC) or x-api-key (debits credits).

- Auth: Dual-auth: send a per-call x402 `X-PAYMENT` header to pay USDC per request with no onboarding, OR send `x-api-key: <API_KEY>` to bill credits. The two paths are mutually exclusive — pick one per request.
- Billing: Per-token

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `messages` | array | yes | Chat messages. |
| `model` | enum | no | Gemini model: gemini-2.5-flash (default), gemini-2.5-flash-lite (cheapest), gemini-2.5-pro (most capable), gemini-3.1-flash-lite (newer Lite, better reasoning), or gemini-3.5-flash (newest Pro-tier reasoner). Per-token rate varies by model — see the rate sheet on the home page. |
| `memory_read` | boolean | no | Retrieve memory context. Default true. |
| `memory_write` | boolean | no | Store user/assistant memory. Default true. |
| `memory_write_mode` | enum | no | auto\|raw\|summary for memory writes. Default auto. |
| `memory_max_chars` | integer | no | Max chars stored per memory write artifact. Default 1200. |
| `k` | integer | no | Top-k memories. |
| `temperature` | number | no | Generation temperature. |
| `stream` | boolean | no | Emit OpenAI-compatible SSE chunks instead of a single JSON response. Default false. Only valid on the api-key path; x402 requests with stream:true return 400. |

**Request body**

```json
{
  "messages":[{"role":"user","content":"Summarize our last run"}],
  "model":"gemini-2.5-flash",
  "memory_read":true,
  "memory_write":true,
  "memory_write_mode":"auto",
  "memory_max_chars":1200,
  "k":5,
  "temperature":0.3,
  "stream":false
}
```

**Response**

```json
{
  "output_text":"...",
  "usage":{
    "memories_used":3,
    "memory_read":true,
    "memory_write":true,
    "model":"gemini-2.5-flash",
    "prompt_tokens":482,
    "completion_tokens":196,
    "summarize_prompt_tokens":1024,
    "summarize_completion_tokens":140,
    "credit_cost":null,
    "usd_cost":"0.000712"
  }
}
// x402 example (default curl tab): usd_cost is set, credit_cost is null.
// On the api-key path the shape inverts — credit_cost is the integer
// credits debited (e.g. 712) and usd_cost is null. The two numbers are
// 1:1 (1 credit = 1 atomic USDC) but only the channel the buyer paid
// through is populated, so agents can branch on field presence.
```

**Example — x402 (no onboarding)**

```bash
curl -X POST https://api.vectorway.io/v1/chat/completions \
  -H "X-PAYMENT: <base64 signed USDC payment>" \
  -H "Content-Type: application/json" \
  -d '{
  "messages":[{"role":"user","content":"Summarize our last run"}],
  "model":"gemini-2.5-flash",
  "memory_read":true,
  "memory_write":true,
  "memory_write_mode":"auto",
  "memory_max_chars":1200,
  "k":5,
  "temperature":0.3,
  "stream":false
}'
```

**Example — API key**

```bash
curl -X POST https://api.vectorway.io/v1/chat/completions \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
  "messages":[{"role":"user","content":"Summarize our last run"}],
  "model":"gemini-2.5-flash",
  "memory_read":true,
  "memory_write":true,
  "memory_write_mode":"auto",
  "memory_max_chars":1200,
  "k":5,
  "temperature":0.3,
  "stream":false
}'
```

---

## Auth (SIWE + JWT, agent-first)

Wallet authentication and JWT session lifecycle for agent-first accounts.

### `POST /v1/auth/agent-onboard`

**Onboard agent with x402 payment.**

Verifies x402 payment, creates account if needed, grants credits, issues a JWT, and returns a new API key.

- Auth: Send the standard x402 `X-PAYMENT` header. The wallet is taken from the verified payment payload.
- Billing: x402 settled

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `wallet_address` | string | yes | Wallet to onboard and credit. |
| `credits` | integer | yes | Credits to add. Min 500,000 (≈$0.50 floor), max 1,000,000,000 (≈$1000 ceiling). 1 credit = 1 atomic USDC = $0.000001 → linear $1 → 1,000,000 credits. |
| `key_name` | string | no | Optional API key display name. |

**Request body**

```json
{
  "wallet_address":"0xabc...",
  "credits":5000000,
  "key_name":"agent-prod"
}
```

**Response**

```json
{
  "wallet_address":"0xabc...",
  "credits":6000000,
  "created":true,
  "agent_only":true,
  "tokens":{
    "access_token":"eyJ...",
    "refresh_token":"eyJ...",
    "token_type":"bearer",
    "expires_in":900
  },
  "api_key":"vw_...",
  "api_key_metadata":{
    "key_id":"abc123",
    "key_name":"agent-prod",
    "created_at":1747000000,
    "last_used_at":null
  }
}
```

**Example**

```bash
curl -X POST https://api.vectorway.io/v1/auth/agent-onboard \
  -H "X-PAYMENT: <base64 signed USDC payment>" \
  -H "Content-Type: application/json" \
  -d '{
  "wallet_address":"0xabc...",
  "credits":5000000,
  "key_name":"agent-prod"
}'
```

---

### `POST /v1/auth/siwe/challenge`

**Generate SIWE challenge message.**

Creates nonce-backed SIWE message for a wallet.

- Auth: No authentication required.
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `wallet_address` | string | yes | Wallet address for challenge issuance. |
| `chain_id` | integer | no | EVM chain ID. Default 1. |

**Request body**

```json
{
  "wallet_address": "0xabc...",
  "chain_id": 1
}
```

**Response**

```json
{
  "wallet_address": "0xabc...",
  "message": "localhost wants you to sign in...",
  "nonce": "f3a9...",
  "expires_in_seconds": 300
}
```

**Example**

```bash
curl -X POST https://api.vectorway.io/v1/auth/siwe/challenge \
  -H "Content-Type: application/json" \
  -d '{
  "wallet_address": "0xabc...",
  "chain_id": 1
}'
```

---

### `POST /v1/auth/siwe/verify`

**Verify SIWE and issue JWT session.**

Verifies signature + nonce, creates/loads an agent-first account, and returns access + refresh JWTs.

- Auth: Body includes a SIWE `message` + wallet `signature`; no token header required.
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `wallet_address` | string | yes | Wallet being authenticated. |
| `message` | string | yes | SIWE message returned by challenge. |
| `signature` | string | yes | Wallet signature over SIWE message. |

**Request body**

```json
{
  "wallet_address": "0xabc...",
  "message": "localhost wants you to sign in...",
  "signature": "0x..."
}
```

**Response**

```json
{
  "wallet_address": "0xabc...",
  "credits": 100000,
  "created": true,
  "tokens": {
    "access_token": "eyJ...",
    "refresh_token": "eyJ...",
    "token_type": "bearer",
    "expires_in": 900
  }
}
```

**Example**

```bash
curl -X POST https://api.vectorway.io/v1/auth/siwe/verify \
  -H "Content-Type: application/json" \
  -d '{
  "wallet_address": "0xabc...",
  "message": "localhost wants you to sign in...",
  "signature": "0x..."
}'
```

---

### `POST /v1/auth/refresh`

**Rotate refresh token.**

Consumes current refresh token and returns a new access+refresh pair.

- Auth: No authentication required.
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `refresh_token` | string | yes | Current refresh JWT. |

**Request body**

```json
{"refresh_token":"eyJ..."}
```

**Response**

```json
{
  "access_token":"eyJ...",
  "refresh_token":"eyJ...",
  "token_type":"bearer",
  "expires_in":900
}
```

**Example**

```bash
curl -X POST https://api.vectorway.io/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refresh_token":"eyJ..."}'
```

---

### `POST /v1/auth/revoke`

**Revoke refresh token.**

Invalidates provided refresh token (logout).

- Auth: No authentication required.
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `refresh_token` | string | yes | Refresh JWT to revoke. |

**Request body**

```json
{"refresh_token":"eyJ..."}
```

**Response**

```json
{"status":"revoked"}
```

**Example**

```bash
curl -X POST https://api.vectorway.io/v1/auth/revoke \
  -H "Content-Type: application/json" \
  -d '{"refresh_token":"eyJ..."}'
```

---

## Accounts

Wallet account state, compatibility aliases, and API call history.

### `GET /v1/me`

**Get current account state.**

JWT-gated account profile for the authenticated wallet.

- Auth: Send `Authorization: Bearer <ACCESS_JWT>` (control-plane).
- Billing: free

**Response**

```json
{
  "wallet_address":"0xabc...",
  "credits":1240000,
  "created":false
}
```

**Example**

```bash
curl https://api.vectorway.io/v1/me \
  -H "Authorization: Bearer <ACCESS_JWT>"
```

---

### `GET /v1/usage`

**List API call history.**

Wallet-scoped call history (newest first).

- Auth: Send `Authorization: Bearer <ACCESS_JWT>` OR `x-api-key: <API_KEY>` — the wallet is derived from whichever credential is presented. Used by read-only history endpoints (`/v1/usage`, `/v1/credits/ledger`) so both dashboard JWT sessions and runtime api-key callers can audit their own wallet.
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | integer | no | Events per page. 1–100, default 50. |
| `cursor` | integer | no | Opaque list offset from a previous response's next_cursor. Omit for the first page. |
| `filter` | string | no | Either "all" (default), "errors" (status ≥ 400), or an exact request path (e.g. "/v1/chat/completions") for path-scoped reads. |

**Query string**

```text
?limit=50&cursor=0&filter=all
```

**Response**

```json
{
  "wallet_address":"0xabc...",
  "events":[
    {
      "ts":1747000123.45,
      "ts_iso":"2026-05-21T03:24:00Z",
      "method":"POST",
      "path":"/v1/chat/completions",
      "status":200,
      "latency_ms":1234,
      "credits":712,
      "usd_cost":"0.000712",
      "model":"gemini-2.5-flash",
      "prompt_tokens":482,
      "completion_tokens":196,
      "memory_read":true,
      "memory_write":true,
      "memories_used":3,
      "key_id":null,
      "auth_mode":"x402"
    }
  ],
  "next_cursor":50,
  "has_more":true,
  "total":234
}
```

**Example**

```bash
curl https://api.vectorway.io/v1/usage?limit=50&cursor=0&filter=all \
  -H "Authorization: Bearer <ACCESS_JWT>"
```

---

## Credits & Billing

Top-ups, Stripe checkout, balance, and the credit-movement ledger.

### `POST /v1/credits/purchase`

**Top up credit balance via x402.**

x402 payment proof endpoint. Wallet must already have an account and match the wallet in the payment proof.

- Auth: Send the standard x402 `X-PAYMENT` header. The wallet is taken from the verified payment payload.
- Billing: x402 settled

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `wallet_address` | string | yes | Wallet to credit. |
| `credits` | integer | yes | Credits to add (1 credit = 1 atomic USDC = $0.000001). Min 500,000 (≈$0.50), max 1,000,000,000 (≈$1000). |

**Request body**

```json
{"wallet_address":"0xabc...","credits":5000000}
```

**Response**

```json
{"wallet_address":"0xabc...","credits":6000000,"created":false}
```

**Example**

```bash
curl -X POST https://api.vectorway.io/v1/credits/purchase \
  -H "X-PAYMENT: <base64 signed USDC payment>" \
  -H "Content-Type: application/json" \
  -d '{"wallet_address":"0xabc...","credits":5000000}'
```

---

### `GET /v1/credits/me`

**Get credit balance for current account.**

Works with JWT bearer (control plane) or API key (runtime). `credits` is the wallet's current credit balance (1 credit = $0.000001).

- Auth: Send `Authorization: Bearer <ACCESS_JWT>` (control-plane).
- Billing: free

**Response**

```json
{"wallet_address":"0xabc...","credits":2000000}
```

**Example**

```bash
curl https://api.vectorway.io/v1/credits/me \
  -H "Authorization: Bearer <ACCESS_JWT>"
```

---

### `GET /v1/credits/ledger`

**List credit-movement history.**

Wallet-scoped credit ledger (newest first) covering top-ups, refunds, and grants.

- Auth: Send `Authorization: Bearer <ACCESS_JWT>` OR `x-api-key: <API_KEY>` — the wallet is derived from whichever credential is presented. Used by read-only history endpoints (`/v1/usage`, `/v1/credits/ledger`) so both dashboard JWT sessions and runtime api-key callers can audit their own wallet.
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | integer | no | Events per page. 1–100, default 50. |
| `cursor` | integer | no | Opaque list offset from a previous response's next_cursor. |
| `kind` | string | no | Optional filter: "topup" \| "debit" \| "refund" \| "grant". Omit to return every kind. Case-insensitive. |

**Query string**

```text
?limit=50&cursor=0&kind=topup
```

**Response**

```json
{
  "wallet_address":"0xabc...",
  "events":[
    {
      "ts":"2026-05-21T03:24:00Z",
      "kind":"topup",
      "credits":5000000,
      "usd":"5.00",
      "ref":"0xabc...",
      "note":"x402 agent-onboard · 5,000,000 credits"
    }
  ],
  "next_cursor":null,
  "has_more":false,
  "total":1
}
```

**Example**

```bash
curl https://api.vectorway.io/v1/credits/ledger?limit=50&cursor=0&kind=topup \
  -H "Authorization: Bearer <ACCESS_JWT>"
```

---

## API Key Management

API key creation, listing, and revocation.

### `POST /v1/api-keys`

**Create API key.**

JWT control-plane endpoint. Returns raw key once.

- Auth: Send `Authorization: Bearer <ACCESS_JWT>` (control-plane).
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `wallet_address` | string | yes | Wallet owner of key. |
| `key_name` | string | yes | Display name for key. |

**Request body**

```json
{"wallet_address":"0xabc...","key_name":"my-agent"}
```

**Response**

```json
{
  "api_key":"vw_....",
  "metadata":{"key_id":"abc123","key_name":"my-agent","created_at":1747000000,"last_used_at":null}
}
```

**Example**

```bash
curl -X POST https://api.vectorway.io/v1/api-keys \
  -H "Authorization: Bearer <ACCESS_JWT>" \
  -H "Content-Type: application/json" \
  -d '{"wallet_address":"0xabc...","key_name":"my-agent"}'
```

---

### `GET /v1/api-keys`

**List API keys.**

Returns API key metadata for wallet.

- Auth: Send `Authorization: Bearer <ACCESS_JWT>` (control-plane).
- Billing: free

**Response**

```json
[
  {"key_id":"abc123","key_name":"my-agent","created_at":1747000000,"last_used_at":1747000100}
]
```

**Example**

```bash
curl https://api.vectorway.io/v1/api-keys \
  -H "Authorization: Bearer <ACCESS_JWT>"
```

---

### `DELETE /v1/api-keys/{key_id}`

**Revoke API key.**

Deletes selected key if it belongs to wallet.

- Auth: Send `Authorization: Bearer <ACCESS_JWT>` (control-plane).
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `key_id` | path string | yes | API key identifier. |
| `wallet_address` | string | yes | Wallet owner. |

**Request body**

```json
{"wallet_address":"0xabc..."}
```

**Response**

```json
{"status":"revoked","key_id":"abc123"}
```

**Example**

```bash
curl -X DELETE https://api.vectorway.io/v1/api-keys/{key_id} \
  -H "Authorization: Bearer <ACCESS_JWT>" \
  -H "Content-Type: application/json" \
  -d '{"wallet_address":"0xabc..."}'
```

---

## Memory

Read-only introspection over the wallet-scoped vector index. Memory is populated by the chat endpoint when memory_write=true.

### `GET /v1/memory`

**Search memories.**

Semantic search over wallet-scoped memory index. Memory itself is populated by the chat endpoint when memory_write=true; this endpoint is read-only introspection.

- Auth: Send `x-api-key: <API_KEY>` (runtime).
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | yes | Semantic query text. |
| `k` | integer | no | Result count. Default 5. |

**Query string**

```text
?q=last+simulation&k=5
```

**Response**

```json
{"matches":[{"id":"a1b2c3d4-1111-2222-3333-444455556666","text":"...","score":0.91}]}
```

**Example**

```bash
curl https://api.vectorway.io/v1/memory?q=last+simulation&k=5 \
  -H "x-api-key: <API_KEY>"
```

---

### `DELETE /v1/memory/{memory_id}`

**Delete a memory item.**

Deletes a wallet-scoped memory record by id. Use the id returned by a memory-search match.

- Auth: Send `x-api-key: <API_KEY>` (runtime).
- Billing: free

**Parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `memory_id` | path string | yes | Memory identifier returned by GET /v1/memory. |

**Response**

```json
{"status":"deleted","memory_id":"c3d5...-uuid"}
```

**Example**

```bash
curl -X DELETE https://api.vectorway.io/v1/memory/{memory_id} \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '# no body'
```

---
