# DVS tasks integration quickstart Use this workflow to discover IDs and prepare a correct task request without guessing. DVS and DMS name the same public data-management API. The [full DMS reference](filesfm_api_dms.md) describes the actions and field types. ## Prerequisites - A dedicated Files.fm user in an organization with DVS enabled. - An API access token from the account's API-key settings. - Section **write** permission on both `task` and `project_2`, even for API reads. Contact/client lookup needs the corresponding section permission. - The name of the existing project. `project_2` is the DVS projects register; it is not the separate Objects API. Base URL: `https://api.files.fm`. Every DVS action uses **POST JSON** and includes `user` and `user_access_token`. A website session alone and an MCP Bearer token are not this authentication format. Never put credentials in URLs. ## 1. Discover fields and projects ```http POST /api_dvs/task/get_fields Content-Type: application/json {"user":"YOUR_USER","user_access_token":"YOUR_API_TOKEN"} ``` Read `fields[].name`, `type`, `required`, `filter`, `options`, `section`, and `depends_on`. Required task fields currently include `name` and `dvs_project_id`. Dropdown option IDs belong to this organization; example values from documentation are not reusable IDs. The response also contains `actions` (actions this server supports for the section) and `actor` (`{id, org_id}` of the authenticated account). Check `actions` before relying on newer actions such as `search_users` or `get_comments`. ```http POST /api_dvs/project_2/get_documents Content-Type: application/json {"user":"YOUR_USER","user_access_token":"YOUR_API_TOKEN","limit":200,"offset":0} ``` Match the requested project against `items[].name` and retain its integer `dvs_document_id`. Continue with `offset += items.length` until `offset >= total`. Stop and ask for a choice if a name is absent or ambiguous. A short page is not itself the documented completion condition; use `total`. Filters use field names with `filter: true` from `get_fields`. Unknown filter names are ignored, not rejected. Multiple values for a field are OR; different fields are AND. Lists omit HTML descriptions; use `get_document` for full content. ## 2. Discover assignable users and status options ```http POST /api_dvs/task/get_users Content-Type: application/json {"user":"YOUR_USER","user_access_token":"YOUR_API_TOKEN","dvs_project_id":123} ``` Here `123` represents the project ID just discovered. Resolve `users[].display_name` to an integer `id`; do not substitute email addresses or usernames in task user fields. Only use the users returned for that project — `responsible` and `followers` reject other IDs, including IDs found with `search_users`. Resolve `dropdown_status`, `dropdown_priority`, and other dropdown values from the task field's `options`. For external followers, look up `contact_person` document IDs; those are different from platform user IDs. [Contact and client relationships](filesfm_api_dms.md#supported-registers) ## 3. Create a task After discovery, construct this body using the real IDs and any additional required fields: ```json { "user": "YOUR_USER", "user_access_token": "YOUR_API_TOKEN", "create_params": { "dvs_project_id": 123, "name": "Review integration", "responsible": 456, "dropdown_status": 789, "description": "
Review the integration.
" } } ``` Send to `POST /api_dvs/task/create_document`. Optional fields may be omitted. IDs `123`, `456`, and `789` above are illustrative; replace them with discovery results. ```json {"dvs_document_id":4822} ``` Retain the returned task ID. Creation and updates can send notifications. The API has no documented idempotency key: after a timeout or uncertain write outcome, reconcile with task reads before retrying. Invalid relation IDs may fail after part of a write has occurred; a failure is not proof that nothing was saved. ## 3a. Inspect a person's task queue 1. Status ID: from `task/get_fields`, pick the wanted entry of the `dropdown_status` field's `options` by `display_name` and keep its `id`. 2. User ID: for your own queue use `actor.id` from `get_fields`. For someone else, search the organization by name: ```http POST /api_dvs/task/search_users Content-Type: application/json {"user":"YOUR_USER","user_access_token":"YOUR_API_TOKEN","pattern":"anna smith","limit":5} ``` `search_users` returns up to `limit` (max 20) active organization users as `{id, display_name, has_access}`; refine the pattern if the person is not in the result or if several people match. `task/get_users` for a known project is an alternative, but it lists only users assignable in that project. 3. List the queue; both filters are applied on the server (different fields are AND, several values of one field are OR): ```http POST /api_dvs/task/get_documents Content-Type: application/json {"user":"YOUR_USER","user_access_token":"YOUR_API_TOKEN","filters":{"responsible":456,"dropdown_status":[789,790]},"order":"oldest","limit":20} ``` `responsible` matches the task's responsible person only, not followers. Use `task/get_comments` to read and paginate a task's comment history, including author organization and activity. ## 4. Read, update, and comment Call `task/get_document` with auth and `dvs_document_id` to read the full saved record. IDs in read responses are often objects such as `{ "id": 456, "display_name": "..." }`; write requests need the scalar IDs. ```json { "user": "YOUR_USER", "user_access_token": "YOUR_API_TOKEN", "dvs_document_id": 4822, "update_params": { "dropdown_status": 790 } } ``` Send to `POST /api_dvs/task/update_document`. Discover `790` from `get_fields`. This is a partial update: omitted fields keep their values; arrays supplied for workers/relations replace that field's selection. The task's project cannot be changed through this API. ```json { "user": "YOUR_USER", "user_access_token": "YOUR_API_TOKEN", "dvs_document_id": 4822, "comment": "Integration reviewed." } ``` Send to `POST /api_dvs/task/add_comment`. Mention a platform user with `@[USER:456]`; mentions can notify users. There is no documented task delete action in this API. Clean up test records through the authorized DVS UI. ## curl Set credentials in your local environment. The following uses Node to write JSON to stdin, keeping the token out of the URL and curl arguments: ```bash export FILESFM_USER='YOUR_USER' export FILESFM_API_TOKEN='YOUR_API_TOKEN' node -e 'process.stdout.write(JSON.stringify({user:process.env.FILESFM_USER,user_access_token:process.env.FILESFM_API_TOKEN}))' | curl --silent --show-error --fail-with-body --max-time 30 \ 'https://api.files.fm/api_dvs/task/get_fields' \ -H 'Content-Type: application/json' --data-binary @- ``` For write calls, prepare the JSON body from discovered IDs in a local private file and use `--data-binary @request.json`. Protect and remove credential-bearing files after use. Do not use verbose HTTP traces with real credentials. ## JavaScript (Node 18+ or a trusted server) ```js async function dvs(section, action, params = {}) { const response = await fetch(`https://api.files.fm/api_dvs/${section}/${action}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...params, user: process.env.FILESFM_USER, user_access_token: process.env.FILESFM_API_TOKEN }), signal: AbortSignal.timeout(30000) }); const text = await response.text(); if (!response.ok) throw new Error(`DVS HTTP ${response.status}`); if (!text) throw new Error('Missing success response'); return JSON.parse(text); } const { fields } = await dvs('task', 'get_fields'); const projects = []; let offset = 0; while (true) { const page = await dvs('project_2', 'get_documents', { limit: 200, offset }); projects.push(...page.items); offset += page.items.length; if (offset >= page.total) break; if (!page.items.length) throw new Error('Incomplete project listing'); } const matches = projects.filter(p => p.name === process.env.FILESFM_PROJECT_NAME); if (matches.length !== 1) throw new Error('Choose one existing project'); const projectId = matches[0].dvs_document_id; const { users } = await dvs('task', 'get_users', { dvs_project_id: projectId }); const statusOptions = fields.find(f => f.name === 'dropdown_status')?.options || []; // Select a user and status from users/statusOptions; omit them if not needed. const createParams = { dvs_project_id: projectId, name: 'Review integration' }; console.log({ endpoint: '/api_dvs/task/create_document', create_params: createParams }); // Only run the following block when task creation and notifications are authorized: // const created = await dvs('task', 'create_document', { create_params: createParams }); // const task = await dvs('task', 'get_document', { dvs_document_id: created.dvs_document_id }); // await dvs('task', 'update_document', { dvs_document_id: task.dvs_document_id, // update_params: { description: 'Integration verified.
' } }); // await dvs('task', 'add_comment', { dvs_document_id: task.dvs_document_id, // comment: 'Integration reviewed.' }); ``` Keep API tokens on a trusted server, not in shipped browser JavaScript. Client-side UI should call your own authorized integration backend. ## PHP 7.4+ ```php true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode($params, JSON_THROW_ON_ERROR), CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30, ]); $body = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_HTTP_CODE); $failed = $body === false; curl_close($curl); if ($failed) { throw new RuntimeException('DVS transport failed'); } if ($status !== 200) { throw new RuntimeException('DVS HTTP ' . $status); } return json_decode($body, true, 512, JSON_THROW_ON_ERROR); } $fields = dvs('task', 'get_fields')['fields']; $projects = []; $offset = 0; do { $page = dvs('project_2', 'get_documents', ['limit' => 200, 'offset' => $offset]); $projects = array_merge($projects, $page['items']); $offset += count($page['items']); if (!$page['items'] && $offset < $page['total']) { throw new RuntimeException('Incomplete project listing'); } } while ($offset < $page['total']); $matches = array_values(array_filter($projects, function ($p) { return $p['name'] === getenv('FILESFM_PROJECT_NAME'); })); if (count($matches) !== 1) { throw new RuntimeException('Choose one existing project'); } $projectId = $matches[0]['dvs_document_id']; $users = dvs('task', 'get_users', ['dvs_project_id' => $projectId])['users']; $createParams = ['dvs_project_id' => $projectId, 'name' => 'Review integration']; // After explicit write authorization: // $created = dvs('task', 'create_document', ['create_params' => $createParams]); // $task = dvs('task', 'get_document', ['dvs_document_id' => $created['dvs_document_id']]); // dvs('task', 'update_document', ['dvs_document_id' => $task['dvs_document_id'], // 'update_params' => ['description' => 'Integration verified.
']]); // dvs('task', 'add_comment', ['dvs_document_id' => $task['dvs_document_id'], // 'comment' => 'Integration reviewed.']); ``` ## Failure handling and MCP DVS errors can have an empty body. Check status first: `400` parameters, `401` authentication or missing session organization, `405` method/section/permission/not-found conditions, `500` backend failure. Do not log request bodies containing tokens. No universal public DVS request quota is promised; infrastructure can enforce additional limits. Public MCP `filesfm_search_docs` and `filesfm_get_doc` can find and retrieve this guide without auth. Use that content to prepare REST requests. MCP does not create tasks, enumerate DVS projects, or supply your organization's IDs.