# NumeroClaw API Reference

Launch date: 2026-04-04

NumeroClaw should be modeled as an authenticated async reading API.

## Base URL

`https://api.numeroclaw.com`

## Current public product

- `productId`: `theme`
- `profileId`: `evan`
- Current locales: `fr-FR`, `en-US`
- Current public artifacts: `document_v1`, `markdown`, `pdf`
- Standard Theme cost: 20 credits

## Authentication

Public API examples should use the workspace key flow:

- Header: `x-api-key: YOUR_API_KEY`

The platform also accepts bearer-authenticated workspace tokens on portal-backed routes, but `x-api-key` is the clearest public integration path.

## Create reading

Endpoint:

- `POST /api/v1/readings`

Example request:

```bash
curl -X POST https://api.numeroclaw.com/api/v1/readings \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "productId": "theme",
    "profileId": "evan",
    "locale": "en-US",
    "name": {
      "firstNames": ["Marie-France"],
      "middleNames": ["Paulette"],
      "lastNames": ["Dubois"]
    },
    "dateOfBirth": "1990-03-15",
    "grammaticalProfile": { "subjectGender": "F" }
  }'
```

Required request fields:

- `productId`
- `profileId`
- `locale`
- `name.firstNames`
- `name.middleNames`
- `name.lastNames`
- `dateOfBirth`
- `grammaticalProfile.subjectGender`

Notes:

- `dateOfBirth` must be strict `YYYY-MM-DD`
- `name` must use structured birth-name arrays
- public language support is currently limited to French and English

Example accepted response:

```json
{
  "readingId": "9d38d8f5-1a2b-4f70-9b4a-4df9f0a4d131",
  "workspaceId": "workspace_demo",
  "status": "queued",
  "productId": "theme",
  "profileId": "evan",
  "locale": "en-US",
  "input": {
    "name": {
      "firstNames": ["Marie-France"],
      "middleNames": ["Paulette"],
      "lastNames": ["Dubois"]
    },
    "displayName": "Marie-France Paulette Dubois",
    "dateOfBirth": "1990-03-15",
    "grammaticalProfile": { "subjectGender": "F" }
  },
  "document": {
    "available": false,
    "version": null,
    "artifactId": null,
    "publishedAt": null
  },
  "error": null
}
```

## Async lifecycle

NumeroClaw does not promise a universal fixed time-to-result.

Public state values:

- `queued`
- `processing`
- `completed`
- `failed`

Recommended integration shape:

1. Create the reading with `POST /api/v1/readings`
2. Store the returned `readingId`
3. Poll `GET /api/v1/readings/{readingId}` or wait for webhook delivery
4. Fetch `GET /api/v1/readings/{readingId}/result` when complete
5. Pull document formats from `GET /api/v1/readings/{readingId}/document`

## Polling

Status endpoint:

- `GET /api/v1/readings/{readingId}`

Stable result endpoint:

- `GET /api/v1/readings/{readingId}/result`

Polling example:

```js
const baseUrl = 'https://api.numeroclaw.com';

async function numeroclaw(path) {
  const response = await fetch(baseUrl + path, {
    headers: { 'x-api-key': process.env.NUMEROCLAW_API_KEY },
  });

  if (!response.ok) throw new Error(await response.text());
  return response.json();
}

async function waitForReading(readingId, { intervalMs = 10000, maxAttempts = 30 } = {}) {
  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
    const reading = await numeroclaw('/api/v1/readings/' + readingId);

    if (reading.status === 'completed') {
      return numeroclaw('/api/v1/readings/' + readingId + '/result');
    }

    if (reading.status === 'failed') {
      throw new Error('NumeroClaw marked the reading as failed.');
    }

    await new Promise(resolve => setTimeout(resolve, intervalMs));
  }

  throw new Error('Reading is still not complete. Increase your timeout or switch to webhooks.');
}
```

## Webhooks

Webhook management endpoints:

- `GET /api/v1/webhooks`
- `POST /api/v1/webhooks`
- `PATCH /api/v1/webhooks/{endpointId}`

Supported event types:

- `reading.completed`
- `reading.failed`
- `reading.published`
- `reading.delayed`

Create example:

```bash
curl -X POST https://api.numeroclaw.com/api/v1/webhooks \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "url": "https://your-app.example/webhooks/numeroclaw",
    "events": ["reading.published", "reading.failed"]
  }'
```

Webhook security:

- create response includes a one-time `signingSecret`
- deliveries send:
  - `x-numeroclaw-event`
  - `x-numeroclaw-timestamp`
  - `x-numeroclaw-signature`
- signature format: `t={unixTimestamp},v1={hexHmacSha256}`
- signature input: `{timestamp}.{rawBody}`

## Reading retrieval

Workspace resource:

- `GET /api/v1/readings/{readingId}`

Stable result:

- `GET /api/v1/readings/{readingId}/result`

Published document:

- `GET /api/v1/readings/{readingId}/document?format=document_v1`
- `GET /api/v1/readings/{readingId}/document?format=markdown`
- `GET /api/v1/readings/{readingId}/document?format=pdf`

## Output formats

Current public Theme publication produces:

- `document_v1`
- `markdown`
- `pdf`

The public create-reading request does not currently ask the caller to select a format at submission time.

## Errors

Common public errors:

- `400`: invalid request, unsupported locale, unknown product/profile, or invalid webhook URL
- `401`: missing or invalid workspace authentication
- `402`: insufficient credits
- `403`: wrong workspace or wrong auth mode for the route
- `404`: reading, document, or webhook endpoint not found
- `429`: rate limit exceeded, respect `Retry-After`
- `503`: temporary enqueue or billing configuration problem

## Pricing and credits

Current public credit logic:

- `theme` costs 20 credits
- Studio: 400 credits / month / $149
- Pro: 2,000 credits / month / $399
- Growth: 10,000 credits / month / $1,190
- Access Local: 100 credits / month / $49, approval-based regional plan

Current public packs:

- Flex: 50 credits / $29
- Sprint: 200 credits / $99
- Campaign: 500 credits / $199
- Burst: 2,000 credits / $699

## Examples

- French sample excerpt: `/examples/messi-fr.md`
- English launch preview excerpt: `/examples/messi-en.md`
- Human-facing examples page: `/examples/`

## Machine-readable surfaces

- `/llms.txt`
- `/lm.txt`
- `/docs/reference.fr.md`
- `/rss.xml`
