# REST API

The REST API lets you manage files, execute tools, and check container status programmatically. Every MCP tool is available as an HTTP endpoint. It uses the same authentication and credit system as MCP.

## Base URL

<PersonalizedCode
  client:load
  code="https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID"
  title="Your Container's REST API Base URL"
/>

## Authentication

All REST endpoints accept the same credentials as MCP:

- **API Key**: `x-api-key: YOUR_API_KEY` header
- **Bearer Token**: `Authorization: Bearer YOUR_TOKEN` header

On public containers, only the status endpoint is accessible without authentication. All other endpoints (files, upload, delete, claim) require an API key or bearer token.

:::tip[Container-scoped keys are enforced on REST too]
Create keys from the container's **Access** tab so the key only works for that one container. If a scoped key is used against a different container's REST endpoint, Wire returns `403 Forbidden` — the same enforcement that applies to MCP. See [Authentication](/mcp/authentication/#container-scoped-keys-recommended).
:::

See [Authentication](/mcp/authentication/) for details on obtaining credentials.

## Endpoints

### Get Container Status

```
GET /container/:id/status
```

Returns the container's current state: initialization status, tool count, composite and entry counts, entry analysis progress, and analysis metadata. This is the only endpoint accessible on public containers without authentication.

**Example request:**

```bash
curl -H "x-api-key: YOUR_API_KEY" \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/status
```

**Example response:**

```json
{
  "success": true,
  "data": {
    "containerId": "abc123",
    "containerName": "My Container",
    "is_ephemeral": false,
    "initialized": true,
    "initializationStatus": "complete",
    "paused": false,
    "ready": true,
    "counts": {
      "tools": 5,
      "composites": 28,
      "entityTypes": 17,
      "entries": {
        "total": 7381,
        "eligible": 7102,
        "analyzed": 7044,
        "pending": 58
      }
    },
    "analysis": {
      "inProgress": false,
      "cadence": "automatic"
    }
  }
}
```

| Field | Description |
|-------|-------------|
| `ready` | `true` when the container is initialized, complete, and not paused |
| `initializationStatus` | One of: `pending`, `analyzing`, `generating_tools`, `complete` |
| `counts.tools` | Number of active MCP tools |
| `counts.composites` | Number of logical composites (file uploads, agent-write batches, scraped pages, etc.) |
| `counts.entityTypes` | Number of discovered entity types |
| `counts.entries.total` | All entries in the container |
| `counts.entries.eligible` | Entries that are subject to analysis (excludes canonicals and system types) |
| `counts.entries.analyzed` | Eligible entries that have been analyzed at least once |
| `counts.entries.pending` | Eligible entries awaiting their first analysis pass — readiness signal: `0` means every eligible entry has been analyzed |
| `analysis.inProgress` | Whether an analysis pass is currently running |
| `analysis.cadence` | Analysis cadence configured for this container |

### List Files

```
GET /container/:id/files
```

Returns all files uploaded to the container. Requires authentication (no public access).

**Example request:**

```bash
curl -H "x-api-key: YOUR_API_KEY" \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/files
```

**Example response:**

```json
{
  "success": true,
  "data": [
    {
      "id": "file_abc123",
      "name": "document.pdf",
      "size": 245760,
      "mimeType": "application/pdf",
      "uploadedAt": "2026-03-30T12:00:00Z",
      "createdAt": "2026-03-30T12:00:00Z"
    }
  ]
}
```

### Upload File

```
POST /container/:id/files
```

Upload a file using multipart form data. Requires authentication (no public access).

Wire processes the file automatically after upload, extracting entries and building context.

**Example request:**

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -F "file=@customers.csv" \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/files
```

See [Supported File Types](/reference/file-types/) for the complete list of accepted formats.

### Delete File

```
DELETE /container/:id/files/:fileId
```

Delete a file and all its associated entries. Requires authentication (no public access).

**Example request:**

```bash
curl -X DELETE \
  -H "x-api-key: YOUR_API_KEY" \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/files/file_abc123
```

## Tool Endpoints

Every MCP tool is also available as a REST endpoint. These use the same underlying execution engine and credit system as MCP. All tool endpoints accept `POST` with a JSON body.

Credit costs match MCP: 1 credit per tool call, 5 credits for semantic search mode. See [Tools Reference](/reference/tools/) for detailed parameter documentation.

:::note
REST tool endpoints use the 5 default tools (`wire_explore`, `wire_search`, `wire_navigate`, `wire_write`, `wire_delete`). Tool active/inactive status in the dashboard is enforced across both MCP and REST. Deactivating a tool blocks it from being called via either channel.
:::

### Explore

```
POST /container/:id/tools/explore
```

Discover entity types, fields, relationships, and entry counts. Call this first to understand a container's schema before searching.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `entityType` | string | No | Drill into a specific entity type for detailed schema and samples |
| `includeSamples` | boolean | No | Include sample entries (only with `entityType`). Default `false`. |
| `sampleLimit` | number | No | Number of samples (1-10). Default 3. |

**Example request:**

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}' \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/tools/explore
```

**Example response:**

```json
{
  "success": true,
  "data": {
    "totalEntityTypes": 3,
    "totalEntries": 142,
    "entityTypes": [
      { "name": "Customer", "entryCount": 89, "fields": [{ "name": "email", "type": "string" }] }
    ],
    "relationships": [["Customer", "orderId", "Order"]]
  }
}
```

### Search

```
POST /container/:id/tools/search
```

Query data using five modes: `list`, `get`, `filter`, `text`, or `semantic`. Same capabilities as the `wire_search` MCP tool.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `mode` | string | Yes | One of: `list`, `get`, `filter`, `text`, `semantic` |
| `entityType` | string | Depends | Required for `list`, `filter`, `text` modes |
| `query` | string | Depends | Required for `text` and `semantic` modes |
| `id` | string | Depends | Required for `get` mode |
| `filters` | array | No | Field conditions for `filter` mode |
| `limit` | number | No | Max results (default varies by mode) |
| `offset` | number | No | Pagination offset |
| `include` | string[] | No | Related entity types to resolve |

**Example request (semantic search):**

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "semantic", "query": "customer feedback on pricing"}' \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/tools/search
```

**Example request (list mode):**

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "list", "entityType": "Customer", "limit": 10}' \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/tools/search
```

### Write

```
POST /container/:id/tools/write
```

Save a new entry to the container. Requires authentication (not available on public containers).

:::tip[Use this as a webhook source]
Any automation platform that can make an authenticated HTTP POST — **n8n, Zapier, Make, Pipedream, a cron job, a shell script** — can drop entries into a Wire container using this endpoint. Because the URL is fixed and auth is a rotatable API key, this is the recommended way to pipe workflow output into Wire. See the [Sources tab](https://app.usewire.io) inside any container to grab the endpoint URL pre-filled for your container.
:::

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string or object | Yes | Text/markdown string or structured data object |
| `contentType` | string | No | `"text"`, `"markdown"`, or `"structured"`. Inferred from `content` when omitted (strings → `text`, objects → `structured`) |
| `tags` | string[] | No | Tags for lightweight filtering |
| `metadata` | object | No | Key-value metadata stored in entry properties |
| `source` | string | No | Source label. Defaults to `"agent:mcp"` for MCP calls and `"webhook:<api-key-name>"` for REST calls. Override with any `<prefix>:<identifier>` string — common prefixes: `n8n:`, `make:`, `zapier:`, `webhook:`. |

**Example request (curl):**

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content": "Q2 revenue increased 15% driven by enterprise segment", "tags": ["finance", "q2"]}' \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/tools/write
```

**Example request (n8n HTTP Request node):**

Set the node to POST, URL to your container's write endpoint, Authentication to "Generic Credential → Header Auth" with header name `Authorization` and value `Bearer YOUR_API_KEY`. Body:

```json
{
  "content": "{{ $json.summary }}",
  "source": "n8n:{{ $workflow.id }}:{{ $node.name }}",
  "tags": ["{{ $json.category }}"],
  "metadata": {
    "runId": "{{ $execution.id }}"
  }
}
```

**Example response:**

```json
{
  "success": true,
  "data": {
    "entryId": "entry_abc123",
    "message": "Entry queued for storage. It will be searchable within a few seconds."
  }
}
```

**Source field convention.** Wire uses the `source` string to trace where each entry came from. Sticking to the `<platform>:<identifier>` pattern keeps downstream graph exploration tidy:

| Origin | Recommended `source` |
|--------|----------------------|
| Claude Code / other MCP agents | `agent:session-abc` (default: `agent:mcp`) |
| n8n workflow | `n8n:<workflow-id>:<node-id>` |
| Make scenario | `make:<scenario-id>` |
| Zapier zap | `zapier:<zap-id>` |
| Custom script / anything else | `webhook:<descriptive-name>` |

**Credit cost.** Each write is billed the same as a `wire_write` MCP call (1 credit per write plus embedding/analysis overhead). See [Credits & Pricing](https://usewire.io/pricing).

### Delete

```
POST /container/:id/tools/delete
```

Permanently delete an entry and clean up related graph data. Requires authentication (not available on public containers).

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `entryId` | string | Yes | The entry ID to delete (returned by write) |

**Example request:**

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"entryId": "entry_abc123"}' \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/tools/delete
```

### Analysis

Analysis runs passively on a per-container cadence (configurable in the dashboard: Wire / Scheduled / Manual). There is no agent-triggered `tools/analyze` endpoint in production — see [container settings](https://app.usewire.io) to control when analysis runs.

**Example response:**

```json
{
  "success": true,
  "data": {
    "message": "Analysis triggered",
    "workflowId": "wf_abc123"
  }
}
```

## Other Endpoints

### Claim Ephemeral Container

```
POST /container/:id/claim
```

Generate a claim link for an ephemeral container. Returns a URL the user can open to sign up or log in and make the container permanent. Requires authentication.

Returns `409 Conflict` if the container has already been claimed.

**Example request:**

```bash
curl -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  https://YOUR_ORG_SLUG.api.usewire.io/container/YOUR_CONTAINER_ID/claim
```

**Example response:**

```json
{
  "success": true,
  "data": {
    "claim_url": "https://app.usewire.io/onboarding/create-account?claimToken=...",
    "expires_in": 3600
  }
}
```

## Error Responses

All errors follow the same format:

```json
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Unknown endpoint: GET /unknown"
  }
}
```

| Code | HTTP Status | Description |
|------|-------------|-------------|
| `BAD_REQUEST` | 400 | Missing required parameter |
| `UNAUTHORIZED` | 401 | Missing or invalid credentials |
| `FORBIDDEN` | 403 | Action not allowed (e.g., write tools on public access) |
| `INSUFFICIENT_CREDITS` | 402 | Not enough credits to execute tool |
| `NOT_FOUND` | 404 | Container or file not found |
| `TOOL_ERROR` | 422 | Tool execution returned an error |
| `CONFLICT` | 409 | Container already claimed |
| `INTERNAL_ERROR` | 500 | Server error |

## Next Steps

- [Authentication](/mcp/authentication/) — OAuth and API key details
- [Tools Reference](/reference/tools/) — MCP tool documentation
- [Supported File Types](/reference/file-types/) — Accepted upload formats