1. Documents
Handwrite
  • Handwrite Regular Accounts
    • Start here — Handwrite for outside developers
    • API specification notes
    • Socket specification notes
    • Account
      • README — GET /api/v1/me
      • README — DELETE /api/v1/me
      • README — GET /api/v1/me/policy
      • README — GET /api/v1/me/usage
      • Account API — README
      • Who this credential acts for
      • Delete the account (after a 30-day grace period)
      • What your teams' and classes' policies allow
      • Your own usage, and what your teams and classes counted
    • Documents
      • README — GET /api/v1/documents
      • README — POST /api/v1/documents
      • README — GET /api/v1/documents/search
      • README — GET /api/v1/documents/{id}
      • README — PATCH /api/v1/documents/{id}
      • README — DELETE /api/v1/documents/{id}
      • README — GET /api/v1/documents/{id}/content
      • README — PUT /api/v1/documents/{id}/content
      • README — POST /api/v1/documents/{id}/live
      • README — GET /api/v1/export
      • Documents API — README
      • List your documents (or shared, or changes since)
        GET
      • Create a document
        POST
      • Search your own and shared documents
        GET
      • A document's metadata
        GET
      • Change title, text, content type or language
        PATCH
      • Delete a document (owner)
        DELETE
      • The document's text
        GET
      • Replace the text
        PUT
      • Join the document's live co-editing room
        POST
      • Every document you own, with its text
        GET
    • Files
      • README — GET /api/v1/documents/{id}/file
      • README — POST /api/v1/documents/{id}/file
      • README — POST /api/v1/documents/{id}/file/commit
      • README — POST /api/v1/documents/{id}/extract
      • Files API — README
      • Download the original file
      • Start uploading the original file
      • Make an uploaded file the document's file
      • Replace the text with the file's text
    • Audio
      • README — GET /api/v1/documents/{id}/audio
      • README — POST /api/v1/audio/stream
      • README — POST /api/v1/audio/speech
      • README — GET /api/v1/voices
      • README — GET /api/v1/quota
      • Audio API — README
      • The whole document as one audio file
      • Stream speech as it's made
      • Speech with word timings (read-along)
      • Voices you can use
      • Characters left, limit, plan and reset time
    • Sharing
      • README — GET /api/v1/documents/{id}/permissions
      • README — POST /api/v1/documents/{id}/permissions
      • README — PATCH /api/v1/documents/{id}/permissions/{principal}
      • README — DELETE /api/v1/documents/{id}/permissions/{principal}
      • README — DELETE /api/v1/documents/{id}/invitations/{inviteId}
      • README — GET /api/v1/invitations
      • README — POST /api/v1/invitations/{id}/accept
      • README — POST /api/v1/invitations/{id}/decline
      • Sharing API — README
      • Who a document is shared with
      • Share by principal, or invite by email (owner)
      • Change someone's role (owner)
      • Remove access (owner, or leave yourself)
      • Cancel a pending invitation (owner)
      • Document invitations to your verified email
      • Accept a document invitation
      • Decline a document invitation
    • Settings
      • README — GET /api/v1/settings
      • README — PATCH /api/v1/settings
      • Settings API — README
      • Synced app and reader settings
      • Change settings (per key, the newer updatedAt wins)
    • Webhooks
      • Incoming webhook delivery — README
      • README — GET /api/v1/webhooks
      • README — POST /api/v1/webhooks
      • README — GET /api/v1/webhooks/{id}
      • README — DELETE /api/v1/webhooks/{id}
      • Webhooks API — README
      • Your webhook endpoints
      • Register an endpoint (up to 10)
      • One endpoint
      • Delete an endpoint (queued retries are dropped)
    • Meta
      • README — GET /api/v1/openapi.json
      • Meta API — README
      • This OpenAPI description
    • OAuth
      • README — POST /api/oauth/token
      • README — POST /api/oauth/revoke
      • OAuth API — README
      • Exchange a code, or refresh
      • Revoke a token (RFC 7009)
    • Live socket
      • Live document socket — README
    • A document or sharing event
  1. Documents

README — POST /api/v1/documents

Create a document

POST /api/v1/documents · Operation ID: createDocument

Purpose and app behavior

Create only after the user chooses to add/import content. In the personal workflow omit owner; an organisation owner requires separate management permissions. Save the returned ID and revision. Reuse an Idempotency-Key only for an identical retry of this creation.

Authentication

Bearer token with documents:write. Resource access and effective policy still apply.

Example request

Replace all REPLACE_* placeholders and environment values with data for your authorized test account. Use a new UUID in IDEMPOTENCY_KEY for each logical action where shown; use the actual latest revision for If-Match. Examples of writes change real data if run.

curl --fail-with-body -X POST 'https://handwrites.io/api/v1/documents' \
  -H "Authorization: Bearer $HANDWRITE_API_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"title":"Field notes","content":"The heron came back.","contentType":"text/plain"}'

Parameters

NameLocationRequiredMeaning
Idempotency-KeyheaderNo1–255 visible ASCII characters (a UUID per operation). A retry with the same key and identical request within 24 hours replays the first 2xx response with Idempotent-Replayed: true; a different request with the key gets 422 idempotency_mismatch; a retry while the first runs gets 409 idempotency_in_progress.

Request body

application/json (required).

FieldRequiredMeaning
titleYesstring
contentNoUp to 4 MB.
contentTypeNoSee API schema
languageNoA BCP 47 language tag.
ownerNoA team or class you manage, to create the document for it: team: or class:.

Responses

StatusMeaningBody format
201Created at revision 1.application/json
400invalid_request (the message names the field), validation_failed.application/json
401unauthorized: no token, or it's invalid, revoked or expired.application/json
403insufficient_scope, forbidden (you can see it but not do this), app_test_restricted, account_deleted (the account is scheduled for deletion; any request).application/json
404not_found: it doesn't exist or you can't see it (never 403 for documents you can't see).application/json
409conflict (changed meanwhile, already a member) or idempotency_in_progress (with Retry-After).application/json
413too_large (text over 4 MB) or too_long (audio over its limit).application/json
422limit_reached, idempotency_mismatch, unreadable_file, no_text, empty_document.application/json
429rate_limited (burst or daily cap) or quota_exceeded (no characters left).application/json
500internal_error.application/json

Use the paired API reference for complete request/response schemas. See API specification notes for rate limits, error handling, safe retries and additional policy/plan failures. For binary or empty responses, do not call a JSON parser.

Modified at 2026-10-26 12:59:30
Previous
README — GET /api/v1/documents
Next
README — GET /api/v1/documents/search
Built with