Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/deploy-oss.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,23 @@ jobs:
fi
base_url="${DOCS_PUBLIC_URL%/}"
curl --fail --silent --show-error "$base_url/index.html" --output /tmp/calle-docs-index.html
curl --fail --silent --show-error "$base_url/quickstart" --output /tmp/calle-docs-quickstart.html
curl --fail --silent --show-error "$base_url/quickstart.md" --output /tmp/calle-docs-quickstart.md
curl --fail --silent --show-error "$base_url/llms.txt" --output /tmp/calle-docs-llms.txt
curl --fail --silent --show-error "$base_url/llms-full.txt" --output /tmp/calle-docs-llms-full.txt
curl --fail --silent --show-error "$base_url/sitemap.xml" --output /tmp/calle-docs-sitemap.xml
curl --fail --silent --show-error "$base_url/openapi/calle.openapi.yaml" --output /tmp/calle-docs-openapi.yaml
test -s /tmp/calle-docs-index.html
test -s /tmp/calle-docs-quickstart.html
test -s /tmp/calle-docs-quickstart.md
test -s /tmp/calle-docs-llms.txt
test -s /tmp/calle-docs-llms-full.txt
test -s /tmp/calle-docs-sitemap.xml
test -s /tmp/calle-docs-openapi.yaml
cmp --silent dist/index.html /tmp/calle-docs-index.html
cmp --silent dist/quickstart.html /tmp/calle-docs-quickstart.html
cmp --silent dist/quickstart.md /tmp/calle-docs-quickstart.md
cmp --silent dist/llms.txt /tmp/calle-docs-llms.txt
cmp --silent dist/llms-full.txt /tmp/calle-docs-llms-full.txt
cmp --silent dist/sitemap.xml /tmp/calle-docs-sitemap.xml
cmp --silent dist/openapi/calle.openapi.yaml /tmp/calle-docs-openapi.yaml
13 changes: 9 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Thanks for helping improve the CALL-E Developer Docs.

## Development setup

This repository requires Node.js 22 or later, pnpm 8.10.2, and Python 3.10 or
later.
This repository requires Node.js 22.12 or later, pnpm 8.10.2, and Python 3.10
or later.

```bash
pnpm install
Expand All @@ -22,11 +22,16 @@ pnpm run validate
## What to change

- Edit narrative documentation in `content/guides/`.
- Edit navigation metadata in `src/docs-nav.ts`.
- Edit the documentation shell and styles in `src/`.
- Edit navigation, metadata, and API Reference behavior in
`zudoku.config.tsx`.
- Edit the CALL-E theme layer in `src/styles.css`.
- Add or update Playwright coverage in `tests/` when navigation, rendering, or
other observable site behavior changes.

Guide frontmatter supplies titles and descriptions to `/llms.txt`. Keep guide
content in portable Markdown where possible so `.md` and `llms-full.txt`
remain useful to automated agents.

The API Reference is built from `openapi/calle.openapi.yaml`. Contract changes
must describe behavior already supported by the public CALL-E Developer API.
If you are proposing a new API capability, open an issue before changing the
Expand Down
28 changes: 20 additions & 8 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ The deployment workflow runs after a push to `main` or a manual dispatch:
4. Start the `production` environment job.
5. Download the exact artifact built by the validation job.
6. Upload it to the explicit `OSS_DEPLOY_PREFIX` in OSS.
7. Verify signed reads of `index.html` and
`openapi/calle.openapi.yaml`.
7. Verify signed reads of the entry page, clean Quickstart route, Markdown and
LLM files, sitemap, and OpenAPI contract.
8. List the destination prefix and confirm every build object exists.
9. Fetch the entry page and OpenAPI document through `DOCS_PUBLIC_URL`, then
compare both files byte-for-byte with the build artifact.
9. Fetch the entry page, clean Quickstart route, Markdown and LLM files,
sitemap, and OpenAPI document through `DOCS_PUBLIC_URL`, then compare them
byte-for-byte with the build artifact.

The build job does not reference deployment secrets. Pull requests from forks
only run CI and cannot access the `production` environment.
Expand All @@ -66,8 +67,14 @@ pnpm run validate
script tests, and Playwright smoke tests.

The build copies `openapi/calle.openapi.yaml` into the public static tree before
Vite emits `dist/`. The Vite config uses relative asset paths so the build works
behind either a domain root or a CDN path prefix.
Zudoku emits `dist/`. The public domain must map the configured OSS prefix to
the domain root because Zudoku assets use root-relative URLs.

Zudoku writes clean routes as files such as `quickstart.html`. The deployment
tool also uploads the same bytes as an extensionless `quickstart` object, and
does the same for nested API Reference routes. This lets OSS serve
`/quickstart` directly without returning an empty app shell or requiring a
global SPA fallback.

## Private OSS and CDN

Expand All @@ -79,11 +86,16 @@ serving them.
Recommended cache behavior:

- `index.html`: no cache or short cache.
- route HTML, extensionless route aliases, `.md`, `llms*.txt`, and
`sitemap.xml`: no cache or short cache.
- `openapi/calle.openapi.yaml`: no cache or short cache.
- `assets/*`: one year, immutable.

The site uses hash routing, so routes such as `#/quickstart` and
`#/api-reference` do not require server-side route rewrites.
Configure the CDN or gateway to check exact OSS objects first and use
`404.html` for unknown paths while preserving the HTTP 404 status. Do not use
an `index.html` SPA fallback: crawlers would receive the wrong page content.
The root entry page contains a small client bridge for old links such as
`/#/quickstart` and `/#/api-reference`.

## Manual dry run

Expand Down
31 changes: 24 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ layout, and pull request checklist.

Requirements:

- Node.js 22 or later
- Node.js 22.12 or later
- pnpm 8.10.2
- Python 3.10 or later

Expand All @@ -27,7 +27,7 @@ pnpm install
pnpm run dev
```

The local server runs at `http://127.0.0.1:5174`.
The local server runs at `http://localhost:5174`.

Run the complete validation suite before opening a pull request:

Expand All @@ -39,23 +39,40 @@ pnpm run validate
## Repository layout

- `content/guides/` contains the hand-written MDX guides.
- `src/` contains the React documentation shell and styles.
- `zudoku.config.tsx` defines navigation, search, branding, API Reference, and
machine-readable documentation output.
- `src/styles.css` contains the small CALL-E theme layer on top of Zudoku.
- `openapi/calle.openapi.yaml` is the public API contract used by the API
Reference.
- `public/` contains static brand assets, crawler policy, and the synchronized
OpenAPI copy.
- `tests/` contains Playwright smoke tests.
- `scripts/` contains the OpenAPI sync and static-build verification scripts.
- `scripts/` contains OpenAPI sync, static-build verification, and OSS
deployment tooling.

The build copies `openapi/calle.openapi.yaml` to
`public/openapi/calle.openapi.yaml` and emits the static site to `dist/`.
`public/openapi/calle.openapi.yaml` and asks Zudoku to emit the static site to
`dist/`.

Each guide is published in both human- and agent-readable forms:

- `/quickstart` is a prerendered HTML page.
- `/quickstart.md` is the raw Markdown version.
- `/llms.txt` indexes every guide plus the API Reference and raw OpenAPI
contract.
- `/llms-full.txt` contains the complete guide corpus.
- `/openapi/calle.openapi.yaml` remains the authoritative machine-readable API
contract because OpenAPI Reference pages do not have Markdown exports.
- `/sitemap.xml` and `/robots.txt` provide crawler discovery.

The backend contract is the source of truth for the Developer API. The OpenAPI
file in this repository is the public snapshot used to build and publish the
API Reference.

## Scope

The site is documentation-only. The API Reference is read-only and does not
send live CALL-E API requests from the browser.
The site is documentation-only. Zudoku's API playground is disabled, so the
API Reference cannot send live CALL-E API requests from the browser.

## License

Expand Down
19 changes: 11 additions & 8 deletions content/guides/authentication.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Authentication
---
title: Authentication
description: Use API keys safely from trusted server environments.
---

CALL-E uses project API keys for server-to-server requests.

<h2 id="api-keys">API keys</h2>
## API keys

The CALL-E team provisions API keys for approved projects.

Expand All @@ -16,7 +19,7 @@ export CALLE_API_KEY="calle_test_key"

Do not commit API keys, print them in logs, send them to browser code, or store them in mobile apps. The CALL-E SDKs are server SDKs for trusted backend services and workers.

<h2 id="authorization-header">Authorization header</h2>
## Authorization header

Send the API key as a bearer token:

Expand Down Expand Up @@ -51,7 +54,7 @@ client = CalleClient(
)
```

<h2 id="environments">Environments</h2>
## Environments

Use an explicit base URL in each environment so staging jobs do not accidentally send live calls.

Expand All @@ -61,7 +64,7 @@ export CALLE_BASE_URL="https://api.heycall-e.com"

The example SDK servers and call scripts read `CALLE_BASE_URL` when you provide it. Keep test and production API keys separate, and do not reuse idempotency keys across environments.

<h2 id="server-only">Server-only usage</h2>
## Server-only usage

Only call the Developer API from trusted server code:

Expand All @@ -72,7 +75,7 @@ Only call the Developer API from trusted server code:

Do not call the Developer API directly from a browser, public frontend, or untrusted client. If a frontend user needs to start a call, send the request to your backend first, validate the user, and let your backend call CALL-E with its project API key.

<h2 id="webhook-secrets">Webhook secrets</h2>
## Webhook secrets

Webhook secrets are different from API keys.

Expand All @@ -82,9 +85,9 @@ Use API keys to authenticate your outbound requests to CALL-E. Use webhook secre
export CALLE_WEBHOOK_SECRET="whsec_test_key"
```

Verify `CALL-E-Timestamp` and `CALL-E-Signature` against the raw request body. See the [Webhooks](#/webhooks) guide for runnable server examples.
Verify `CALL-E-Timestamp` and `CALL-E-Signature` against the raw request body. See the [Webhooks](/webhooks) guide for runnable server examples.

<h2 id="auth-errors">Auth errors</h2>
## Auth errors

`401 unauthorized` means the API key is missing, malformed, expired, or invalid. Check the `Authorization: Bearer` header and the environment variable loaded by the running process.

Expand Down
77 changes: 66 additions & 11 deletions content/guides/calls.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Calls
---
title: Calls
description: Understand the call creation contract and event flow.
---

Use call tasks to turn a structured workflow step into one or more real phone interactions.

<h2 id="call-inputs">Call inputs</h2>
Use the [Calls API Reference](/api-reference/calls) for the exact HTTP request
and response schemas. See the [error handling guide](/errors) for retry
behavior and the [terminal webhooks guide](/webhooks) for asynchronous
completion.

## Call inputs

`task` is the natural-language instruction for the call task. Keep it specific and outcome-oriented.

Expand All @@ -20,6 +28,53 @@ Examples use phone placeholders such as `<E164_PHONE>` and `<RECIPIENT_1_E164_PH

The server SDKs also reserve a `context` input for future SDK-side workflow data. It is not sent to the API yet.

## Direct HTTP with curl

Set your API key, then create a call with a stable idempotency key. Replace
`<E164_PHONE>` with a phone number you own or are authorized to call.

```bash
export CALLE_API_KEY="<CALLE_API_KEY>"

curl --fail-with-body --silent --show-error \
--request POST "https://api.heycall-e.com/v1/calls" \
--header "Authorization: Bearer $CALLE_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: wf_123_hearing_check" \
--data '{
"task": "Call <E164_PHONE> and ask whether they can hear clearly.",
"result_schema": {
"type": "object",
"required": ["can_hear_clearly"],
"properties": {
"can_hear_clearly": {
"type": "string",
"enum": ["yes", "no", "unknown"]
}
},
"additionalProperties": false
},
"metadata": {
"workflow_run_id": "wf_123"
}
}'
```

The response contains the call task `id`. Use it to read the current state or
the ordered lifecycle events:

```bash
export CALLE_CALL_ID="<CALL_ID>"

curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $CALLE_API_KEY" \
"https://api.heycall-e.com/v1/calls/$CALLE_CALL_ID"

curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $CALLE_API_KEY" \
"https://api.heycall-e.com/v1/calls/$CALLE_CALL_ID/events?limit=50"
```

TypeScript:

```ts
Expand Down Expand Up @@ -82,7 +137,7 @@ call = client.calls.create(
)
```

<h2 id="structured-results">Structured results</h2>
## Structured results

Structured results let you turn the terminal call evidence into a stable JSON object for your workflow. The schema is an extraction contract: the SDK sends the schema to CALL-E, CALL-E extracts a result from the completed call evidence, and the service validates the result before returning it.

Expand Down Expand Up @@ -132,7 +187,7 @@ resultSchema: {

When a result drives automation, add an evidence field so your system can inspect why CALL-E made the classification.

<h3 id="sales-handoff-result">Sales handoff</h3>
### Sales handoff

Use this pattern when a prospect should be routed to a human if they ask for help or show strong interest.

Expand Down Expand Up @@ -174,7 +229,7 @@ resultSchema: {
}
```

<h3 id="appointment-confirmation-result">Appointment confirmation</h3>
### Appointment confirmation

Use this pattern when calling a business to confirm, reschedule, or cancel an appointment.

Expand Down Expand Up @@ -204,7 +259,7 @@ resultSchema: {
}
```

<h3 id="batch-recipient-result">Batch recipient result</h3>
### Batch recipient result

Use `recipientResultSchema` when each recipient should have their own answer.

Expand All @@ -229,7 +284,7 @@ recipientResultSchema: {
}
```

<h3 id="support-triage-result">Support triage</h3>
### Support triage

Use this pattern when a call should determine whether an issue was resolved or needs follow-up.

Expand Down Expand Up @@ -266,7 +321,7 @@ resultSchema: {
}
```

<h3 id="pricing-request-result">Pricing or quote request</h3>
### Pricing or quote request

Use this pattern when a prospect may ask about pricing, quotes, discounts, or budget.

Expand Down Expand Up @@ -297,7 +352,7 @@ resultSchema: {
}
```

<h3 id="structured-result-best-practices">Best practices</h3>
### Best practices

- Keep schemas focused. A small schema with clear fields is more reliable than a large schema with many optional fields.
- Put enum selection rules in the field `description`.
Expand All @@ -307,13 +362,13 @@ resultSchema: {
- Add an evidence or summary field when the result triggers workflow automation.
- Do not rely on `description` for validation. Use schema constraints for enforceable behavior.

<h2 id="idempotency">Idempotency</h2>
## Idempotency

Pass an idempotency key when a workflow step might retry. The key maps to the `Idempotency-Key` HTTP header and prevents duplicate call creation for the same external operation.

Use a stable workflow key, not a random UUID generated at each retry.

<h2 id="polling-and-events">Polling and events</h2>
## Polling and events

Use `waitForResult` or `wait_for_result` for simple server-side polling. Use events when you need a developer-facing trace of the call lifecycle.

Expand Down
Loading