Factuarea APIDevelopers
Contract

Tasks refinements

Tighter limits and clearer errors in Projects and Tasks: a 400,000-character task description, a 99,999,999.99 hourly rate, entity links that respect scopes, the task id in notifications, deletes blocked by invoiced hours and idempotent time invoicing. users:read becomes a sensitive scope.

30 September 2026 — The review of the Projects and Tasks module tightens a few contracts published in Projects and tasks. No operation is added or removed, and no parameter or response code changes; what changes are limits, error causes and the text of the schemas. Fifteen operations are updated, listed at the end.

  • Task description — POST /v1/tasks and PUT /v1/tasks/{task} declare maxLength: 400000 on description. Above that, the call returns 422 parameter_invalid_value. Between 100,001 and 400,000 measured characters it still returns 422 task_description_too_large. Sanitizing now neutralizes the tags that are not allowed as plain text and no longer truncates the document.
  • Hourly rate of a project — billing_hourly_rate in PUT /v1/projects/{project} accepts at most 99,999,999.99, so the tax of one hour always fits an invoice line.
  • Linked entities and scopes — GET /v1/tasks/{task}/entity-links and POST /v1/tasks/{task}/entity-links include the summary of a linked entity only if the credential has the read scope of the resource that owns it (for example invoices:read for an invoice). Without it the link is still returned, with available: false and summary: null, so it can be removed.
  • entity_id in notifications — GET /v1/notifications returns, for entity_type = task, the UUID of the task in entity_id, ready for GET /v1/tasks/{task}. It used to be always null.
  • users:read is sensitive — it gives access to the whole directory of the company, emails included. Review the keys and OAuth apps that request it; see Scopes & permissions.
  • Deleting with invoiced hours — deleting a task (DELETE /v1/tasks/{task}), a project (DELETE /v1/projects/{project}) or a selection (POST /v1/tasks/bulk-delete) that has invoiced hours returns 422 task_time_entry_invoiced. In a selection nothing is deleted. Delete the invoice first.
  • Invoicing time is idempotent — POST /v1/projects/{project}/time-invoices answers 409 idempotency_key_reused if a batch_id is sent again with a different request, and 409 idempotency_key_in_use while the first one is still running. The same request returns the same invoice. If the amount of a line does not fit the invoice, both this operation and its preview return 422 task_time_not_invoiceable.
  • Scopes of import, export and summary — the description of POST /v1/projects/{project}/tasks/import, GET /v1/projects/{project}/tasks/export and GET /v1/projects/{project}/time-summary now states which scopes they require (only the projects ones).
  • Ids in deletions — the deleted: true responses return the canonical id in lower case.

Error codes: task_description_too_large, task_time_entry_invoiced, task_time_not_invoiceable, idempotency_key_reused and idempotency_key_in_use.

Updated endpoints15

EndpointDescription
POST/v1/tasksCreate a task
PUT/v1/tasks/{task}Update a task
POST/v1/tasks/bulk-deleteBulk delete tasks
DEL/v1/tasks/{task}Delete a task
GET/v1/tasks/{task}/entity-linksList task entity links
POST/v1/tasks/{task}/entity-linksLink a task to an entity
GET/v1/projects/{project}Retrieve a project
PUT/v1/projects/{project}Update a project
DEL/v1/projects/{project}Delete a project
GET/v1/projects/{project}/tasks/exportExport project tasks
POST/v1/projects/{project}/tasks/importImport tasks into a project
GET/v1/projects/{project}/time-summaryRetrieve a project time summary
POST/v1/projects/{project}/time-invoices/previewPreview a project time invoice
POST/v1/projects/{project}/time-invoicesInvoice project time
GET/v1/notificationsList notifications