Skip to main content

Docs / API

Quilvo API reference

Versioned JSON endpoints for projects and writing sessions.

Version v1https://quilvo.app/api/v1MCP guide Developer overview

Start here

The public API currently exposes the minimum surface needed for integrations to discover projects and log writing progress. This page documents the public project and session endpoints available today. For AI assistants, see the MCP guide.

Base URLhttps://quilvo.app/api/v1
Formatapplication/json
AuthenticationBearer token
Public abilitiesprojects:* / sessions:*

Bearer tokens

Users create public API keys from Settings / API Keys. Each key can be limited to the project and session abilities needed by the integration.

Authorization: Bearer YOUR_API_KEY
Accept: application/json
Content-Type: application/json

Abilities

AbilityDescription
projects:readRead projectsList projects and read project details.
projects:writeWrite projectsCreate projects and update project metadata.
sessions:readRead sessionsList writing sessions and read today's session summary.
sessions:writeWrite sessionsCreate single or bulk writing sessions.

Request conventions

  • Send JSON request bodies for write endpoints.
  • Dates use YYYY-MM-DD.
  • Resource IDs are UUID strings.
  • List endpoints use cursor pagination and accept per_page.

Response formats

Paginated lists

{
  "data": [],
  "links": {
    "first": "...",
    "last": "...",
    "prev": null,
    "next": "..."
  },
  "meta": {
    "path": "https://quilvo.app/api/v1/projects",
    "per_page": 25,
    "next_cursor": "...",
    "prev_cursor": null
  }
}

Error responses

{
  "error": {
    "code": "validation_error",
    "message": "The given data was invalid.",
    "details": {
      "word_count": ["The word count field is required."]
    }
  }
}

Project endpoints

Use project endpoints to list existing projects, create projects for a linked tool, or update project metadata. For ordinary word count changes, use session endpoints instead.

GET /projects

List projects for the authenticated user.

Required ability: projects:read

Query parameters

statusactive by default. Use archived or all when needed.
typeFilter by project type, such as novel or short_story.
series_idFilter projects by series UUID.
searchCase-insensitive title search.
per_pageCursor page size. Maximum 100.
GET /projects/{project}

Read one project, including detail fields, recent sessions, and summary stats.

Required ability: projects:read

Response excerpt

{
  "id": "9b7d4f6a-...",
  "title": "Draft novel",
  "type": "novel",
  "status": "drafting",
  "current_word_count": 42100,
  "target_word_count": 80000,
  "target_unit": "words",
  "progress_percent": 52.63,
  "recent_sessions": []
}
POST /projects

Create a project.

Required ability: projects:write

Body fields

FieldTypeRequiredDescription
titlestringCreateProject title.
typestringCreateProject type enum, for example novel.
statusstringNoProject status enum, for example drafting.
target_word_countintegerNoTarget count. Minimum 0.
current_word_countintegerNoBaseline/import count only. Prefer session logging for ongoing changes.
target_datedateNoAlias for target_completion_date.
descriptionstringNoAlias for the short project description.

Request example

{
  "title": "Draft novel",
  "type": "novel",
  "status": "drafting",
  "target_word_count": 80000
}
PATCH /projects/{project}

Update project metadata. This endpoint accepts the same fields as project creation, but all fields are optional.

Required ability: projects:write

{
  "status": "revising",
  "target_word_count": 90000
}

Session endpoints

Session endpoints are the preferred way to update word counts because Quilvo stores the event history and updates the project total for you.

GET /sessions

List writing sessions.

Required ability: sessions:read

Query parameters

project_idFilter sessions for a single project UUID.
date_fromStart date in YYYY-MM-DD format.
date_toEnd date in YYYY-MM-DD format.
per_pageCursor page size. Maximum 100.
GET /sessions/today

Read today's sessions and totals in the account timezone.

Required ability: sessions:read

{
  "date": "2026-05-24",
  "sessions": [],
  "summary": {
    "total_words": 750,
    "total_sessions": 1,
    "total_minutes": 45
  }
}
POST /sessions

Log a single writing session. Use add for deltas or set_total when the client knows the new project total.

Required ability: sessions:write

Retry-safe writes: this endpoint supports an Idempotency-Key header, or a top-level idempotency_key body field. Reuse the same key only for retrying the same request. Keys are stored for 24 hours.

Body fields

FieldTypeRequiredDescription
project_iduuidYesThe project to log progress against.
word_count_actionstringNoadd by default. Use set_total when sending the new project total.
word_countintegerYesFor add, the delta. For set_total, the new total; Quilvo stores the calculated delta.
datedateNoYYYY-MM-DD. Defaults to today. Cannot be in the future.
duration_minutesintegerNoDuration from 0 to 1440 minutes.
notesstringNoOptional session notes. Maximum 1000 characters.

Request example

curl -X POST https://quilvo.app/api/v1/sessions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: local-log-2026-05-24-0830" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "9b7d4f6a-...",
    "word_count_action": "add",
    "word_count": 750,
    "date": "2026-05-24",
    "duration_minutes": 45
  }'

Response excerpt

{
  "session": {
    "id": "9c1a...",
    "project_id": "9b7d4f6a-...",
    "date": "2026-05-24",
    "word_count": 750,
    "unit": "words",
    "duration_minutes": 45
  },
  "today_stats": {
    "total_words": 750,
    "daily_goal": 1000,
    "goal_progress_percent": 75,
    "goal_achieved": false
  }
}
POST /sessions/bulk

Create up to 30 session records in one request. Bulk logging accepts deltas only.

Required ability: sessions:write

Retry-safe writes: this endpoint supports the same Idempotency-Key header or idempotency_key body field as POST /sessions.

Body fields

FieldTypeRequiredDescription
sessionsarrayYes1 to 30 session objects.
sessions.*.project_iduuidYesProject UUID owned by the authenticated user.
sessions.*.datedateYesYYYY-MM-DD. Cannot be in the future.
sessions.*.word_countintegerYesDelta only. set_total is intentionally not supported in bulk.
{
  "sessions": [
    {
      "project_id": "9b7d4f6a-...",
      "date": "2026-05-23",
      "word_count": 320
    }
  ]
}

Status codes

StatusMeaning
200Successful read or replayed write.
201Resource created.
401Missing or invalid bearer token.
403Token is valid but missing the required ability.
404Resource not found or not owned by this account.
409Idempotency key conflict or in-progress request.
422Validation failed. See `error.details`.
429Too many requests.