# REST, TypeScript, Python, and CLI

Canonical human page: https://aune.ai/docs/sdk
Canonical machine page: https://aune.ai/ai/sdk-quickstart.md

The SDKs preserve problem details, retry metadata, idempotency, sandbox routing, and OAuth PKCE helpers. REST remains the source contract; SDK and CLI behavior is contract-tested against it.

## Facts

- **TypeScript:** @aune/sdk
- **Python:** aune-sdk
- **CLI:** @aune/cli
- **Runtime:** Node.js 18+ / Python 3.9+
- **Source contract:** /openapi.json

## TypeScript

### Sandbox client

```typescript
import { randomUUID } from "node:crypto";
import { AuneClient } from "@aune/sdk";

const aune = new AuneClient({ sandbox: true });
const capabilities = await aune.capabilities();
const result = await aune.bookFirstSandboxOption({
  search: {
    vertical_id: "moving",
    job_type_id: "moving_home",
    description: "Synthetic sandbox move",
    location: { country_code: "SE", postcode: "11122" },
    destination_location: { country_code: "SE", postcode: "41256" },
    timing: { preferred_time_text: "next available time" },
  },
  confirmation: {
    customer: { name: "Sandbox User", phone: "+46700000000", email: "sandbox@example.invalid" },
    service_location: { country_code: "SE", address: "Synthetic Origin 1", postcode: "11122" },
    destination_location: { country_code: "SE", address: "Synthetic Destination 2", postcode: "41256" },
    user_consent_confirmed: true,
    booking_terms_accepted: true,
    booking_terms_accepted_at: new Date().toISOString(),
    idempotency_key: randomUUID(),
  },
});
```

## Python

### Sandbox client

```python
from uuid import uuid4
from aune_sdk import AuneClient

aune = AuneClient(sandbox=True)
capabilities = aune.capabilities()
result = aune.book_first_sandbox_option(
    search={
        "vertical_id": "moving",
        "job_type_id": "moving_home",
        "description": "Synthetic sandbox move",
        "location": {"country_code": "SE", "postcode": "11122"},
        "destination_location": {"country_code": "SE", "postcode": "41256"},
        "timing": {"preferred_time_text": "next available time"},
    },
    confirmation={
        "customer": {"name": "Sandbox User", "phone": "+46700000000", "email": "sandbox@example.invalid"},
        "service_location": {"country_code": "SE", "address": "Synthetic Origin 1", "postcode": "11122"},
        "destination_location": {"country_code": "SE", "address": "Synthetic Destination 2", "postcode": "41256"},
        "user_consent_confirmed": True,
        "booking_terms_accepted": True,
        "booking_terms_accepted_at": "2099-01-15T08:01:00.000Z",
        "idempotency_key": str(uuid4()),
    },
)
```

## Complete client surface

- Booking: capabilities, search, confirmation, redacted status, cancellation, and rescheduling.
- Fallback: consented provider-follow-up request creation without upgrading it into booking truth.
- Webhooks: list, create, delete, and replay with OAuth scope `aune.webhooks.manage`.
- OAuth: PKCE S256 pair and authorization URL helpers; token refresh remains under the integrating application's credential store.
- Errors: stable problem codes, safe next step, option-refresh signal, and Retry-After metadata.

## Runnable source starters

### Contract-tested examples

```bash
npx tsx starters/typescript-sandbox/index.ts
npx tsx starters/mcp-jsonrpc/index.ts
npm run test:aune-starters
```

## Release status

The packages are built and contract-tested in this repository. Public npm and PyPI publication, signed provenance, and registry ownership are release gates; do not assume a package is generally available until the changelog marks it published.

## Client invariants

- Search before collecting street address or contact details.
- Treat option IDs as opaque and short-lived.
- Use OAuth scopes for user-delegated writes.
- Preserve payload and idempotency key across uncertain retries.
- Claim confirmation only from the four booking truth signals.
