Skip to Content
HelvetlyDocs
API referenceDocuments

Move, trash or restore documents and folders

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/bulk

The way to trash, restore and bulk-move documents (there is no DELETE on a document): up to 500 ids in total across document_ids and folder_ids, one action: move, trash, restore or delete. Each item is applied on its own and what cannot be done is listed in skipped with a reason (not found, retained, name taken, folder moved into itself, not in the Trash); the call still answers 200. Trashing keeps an item for 30 days and is reversible with restore; a document linked to an issued invoice or a booked or void expense is a business record kept 10 years and cannot be trashed (skipped: retained). 422 validation_failed for an empty or oversized selection or an unknown action. delete removes items that are already in the Trash for good (owner or admin; anything else is skipped: not in the Trash); it cannot be undone, so trash first and delete only on an explicit request. Trashing the same items again is safe.

Authorization

bearerAuth
headerAuthorizationBearer <token>

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

Request Body

application/json
  1. body

Up to 500 documents and folders together (document_ids plus folder_ids) get one action, each applied on its own.

action*string

move: to folder_id (null: top level; name clashes follow on_conflict). trash: into the Trash for 30 days (a folder takes everything inside with it; business records cannot be trashed). restore: out of the Trash (a document whose folder is gone or trashed returns to the top level; a taken name gets " (2)"; a file trashed with its folder is restored through the folder). delete: purge items already in the Trash, irreversibly (owner or admin).

Value in"move""trash""restore""delete"
document_ids?array<string>
folder_ids?array<string>
folder_id?|

Target of move; null: top level.

on_conflict?string

For move only; a clash under fail is skipped.

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

Response Body

OK

application/json
  1. response
data*
Example Request
curl -X POST 'https://app.helvetly.com/api/v1/documents/bulk' \  -H 'Content-Type: application/json' \  -d '{  "action": "trash",  "document_ids": [    "doc_01JABCDEF",    "doc_01JABCDEG"  ]}'
Example Response
{  "data": {    "updated": 0,    "skipped": [      {        "id": "string",        "reason": "string"      }    ]  }}