Customer API
Voice Rewrite API
Rewrite text in your voice seat from the writing app you already use. A human still copies and sends the result. Nothing auto-sends.
OpenAPI: /docs/voice-rewrite.openapi.yaml
Base URL
| Where | URL |
|---|---|
| Local portal | http://localhost:3000 |
| Hosted Apograph | https://apograph.ai |
Routes live under /api/v1. Give the HTTP client at least 120 seconds. Do not point production traffic at localhost. If a response includes "non_production": true, the seat used a desk URL — treat that as dogfood.
Auth
External apps send a Bearer tenant key. Generate a high-entropy secret, set APOGRAPH_TENANT_API_KEY on the portal host, and send the same secret from the writing app. Never put the key in the JSON body, in git, or in tickets. Rotate by generating a new secret, updating the host, then the app. A signed-in portal cookie also works for browser tools.
Authorization: Bearer $APOGRAPH_TENANT_API_KEY Content-Type: application/json
POST /api/v1/voice/rewrite
Rewrite text in the caller’s seat. LUAR is scored in this response (a number, never null, never "async"). If LUAR cannot be scored, the call fails closed with luar_unavailable.
| Field | Required | Notes |
|---|---|---|
| text | yes | Non-empty after trim. Max 150000 characters. |
| voice_seat_id | no | Default c1rw. Unknown seats fail closed. |
| channel | no | email | linkedin_message | note | generic |
| polish | no | false (default) or "light" |
| max_words | no | Positive number. Cap on the voiced draft. |
Copy-paste curl
curl -sS -X POST "$APOGRAPH_BASE_URL/api/v1/voice/rewrite" \
-H "Authorization: Bearer $APOGRAPH_TENANT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
"text": "Thanks for the intro. I can walk through how we measure whether a draft still sounds like the author, then we can pick a time next week.",
"channel": "email",
"polish": false
}
EOFPOST /api/v1/voice/luar
Score-only LUAR after you edit or polish in the writing app. Same auth. Does not rewrite. Does not send.
Copy-paste curl
curl -sS -X POST "$APOGRAPH_BASE_URL/api/v1/voice/luar" \
-H "Authorization: Bearer $APOGRAPH_TENANT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
"text": "Thanks for the intro. I can walk you through how we score whether a draft still sounds like you, then we can find a time next week."
}
EOFErrors
| HTTP | error | What you do |
|---|---|---|
| 401 | unauthorized | Fix the key. Do not retry the same secret. |
| 400 | bad_request | Fix the body. message says which field. |
| 503 | voice_unavailable | Retry after the voice seat is on. No voiced_text. |
| 503 | luar_unavailable | Do not ship. Retry when scoring is up. |
Product LUAR floor is 0.60. A 200 with luar_below_floor: true still includes voiced_text — you decide whether to copy. Token use is returned on rewrite as usage. There is no auto-send and no spend dashboard on this contract.
Wire it in
- Set APOGRAPH_TENANT_API_KEY on the portal host and in the writing app.
- Set APOGRAPH_BASE_URL to localhost or https://apograph.ai.
- POST rewrite. Read voiced_text and luar.
- If luar_below_floor or luar_unavailable, do not send.
- Paste the voiced text. The human hits send in that app.