Skip to Content
HelvetlyDocs
API referenceDocuments

Upload a document

Needs a token with the write:documents scope. Authentication

Try in Playground sends a real request to app.helvetly.com with a token you paste. It stays in this browser tab only (session storage) and goes to no one else.

POST
/api/v1/documents

Uploads one file (multipart field file; one per request) into a folder (folder_id, default top level), optionally linking it to a client (client_id). Allowed types: PDF; PNG, JPEG, WebP, GIF; XLSX, XLS, ODS, CSV; DOCX, DOC, ODT, RTF; PPTX, ODP; TXT, Markdown, XML, JSON; ZIP; the extension and the file's bytes must agree, else 422 validation_failed (fields.file). Larger than DOCUMENTS_MAX_UPLOAD_MB (default 100): 413 payload_too_large. Names are cut to 255 characters and lose path parts. Duplicate check: the SHA-256 of the actual bytes is compared inside the workspace with live documents (client files included) and receipts on non-deleted expenses; identical bytes answer 409 duplicate_file whatever the name, folder or on_conflict, with details {existing_id, existing_name, resource: document or receipt, expense_id?} (only when the caller may read that resource, else a generic message). Trashed documents and deleted expenses do not block; other workspaces never match. A same-named live file in the folder is a name conflict, resolved by on_conflict (fail: 409 name_taken with details {existing_id, suggestion}; keep_both; replace: the old file goes to the Trash, 409 retained if it is a business record); on_conflict applies only to different content. Repeating a successful upload answers 409 duplicate_file.

Authorization

bearerAuth
headerAuthorizationBearer <token>

A personal API token, hvt_…, with scopes such as read:* or write:invoices

Request Body

multipart/form-data
  1. body
file*file

One file per request, up to DOCUMENTS_MAX_UPLOAD_MB (default 100 MB). Allowed: PDF; PNG, JPEG, WebP, GIF; XLSX, XLS, ODS, CSV; DOCX, DOC, ODT, RTF; PPTX, ODP; TXT, Markdown, XML, JSON; ZIP. The extension and the file's bytes must agree.

Formatbinary
folder_id?string

A live folder; absent: top level.

client_id?string

Also link the new document to this client.

on_conflict?string

What to do when a live file with the same name (case-insensitive) is already in the folder.

Default"fail"
Value in"fail""keep_both""replace"

Response Body

Created

application/json
  1. response
data*

A document's metadata. The bytes come from download_document and get_document_content.

Example Request
curl -X POST 'https://app.helvetly.com/api/v1/documents' \  -F 'file=string'
Example Response
{  "data": {    "id": "string",    "name": "string",    "folder_id": "string",    "folder": {      "id": "string",      "name": "string"    },    "size": 0,    "content_type": "string",    "kind": "pdf",    "previewable": true,    "sha256": "string",    "links": [      {        "type": "string",        "id": "string",        "label": "string",        "retains": true      }    ],    "retained_until": "2019-08-24",    "uploaded_by": {      "id": "string",      "name": "string"    },    "created_at": "2019-08-24T14:15:22Z",    "updated_at": "2019-08-24T14:15:22Z",    "deleted_at": "2019-08-24T14:15:22Z",    "deleted_by": {      "id": "string",      "name": "string"    },    "purge_at": "2019-08-24T14:15:22Z"  }}