Skip to main content

Create an Intake and Add an Intake Task

Goal​

Create a legal intake, add an intake task to that intake, update the intake assignee list, and finally delete the intake.

Endpoints used​

  • POST /api/v1/public/legal_intake/
  • PATCH /api/v1/public/legal_intake/{legal_intake_id}/
  • DELETE /api/v1/public/legal_intake/{legal_intake_id}/
  • POST /api/v2.1/public/user_tasks/

Prerequisites​

  • a valid public API key
  • a workflow id for a published INTAKE_WORKFLOW
  • org user ids for anyone you want to assign to the intake or the task

Overview​

Every id in this recipe is workspace-specific. Resolve the workflow id and org user ids first, then substitute them into the requests below.

Request sequence​

1. Create the intake​

import os
import requests

base_url = "https://api.in.spotdraft.com" # Replace with your workspace region.
headers = {
"client-id": SPOTDRAFT_CLIENT_ID,
"client-secret": SPOTDRAFT_CLIENT_SECRET,
"Content-Type": "application/json",
}
workflow_id = int(os.environ["SPOTDRAFT_WORKFLOW_ID"])
org_user_id = os.environ["SPOTDRAFT_ORG_USER_ID"]

intake = requests.post(
f"{base_url}/api/v1/public/legal_intake/",
headers=headers,
json={
"title": "Route new vendor request",
"description": "Initial request for legal review.",
"priority": "MEDIUM",
"workflow_id": workflow_id,
"due_date": "2026-05-05T17:00:00Z",
"assignees": [
{
"entity_id": org_user_id,
"entity_type": "ORG_USER",
"assignee_type": "ASSIGNED_TO",
}
],
"metadata": {"source": "api", "system": "crm"},
},
timeout=30,
).json()

Example response excerpt:

{
"id": 81,
"public_id": "aaf55a1f-0ef1-4bfc-8b0f-3d15b7ed5f02",
"reference_id": "I-0081",
"status": "PENDING",
"priority": "MEDIUM"
}

Extract:

  • id: use this as legal_intake_id for the next steps

2. Create an intake task associated with the intake​

Create the task with task_category set to INTAKE_TASK, then associate it to the intake through task_associations.

legal_intake_id = intake["id"]
task = requests.post(
f"{base_url}/api/v2.1/public/user_tasks/",
headers=headers,
json={
"title": "Collect business justification",
"notes": "Follow up with procurement before legal review starts.",
"assignees": [{"org_user_id": int(org_user_id)}],
"task_category": "INTAKE_TASK",
"priority": "HIGH",
"intake_task_status": "PENDING",
"due_date": "2026-05-01T17:00:00Z",
"task_associations": [
{
"entity_id": legal_intake_id,
"entity_type": "LEGAL_INTAKE",
"association_type": "PRIMARY",
}
],
},
timeout=30,
).json()

Example response excerpt:

{
"id": 501,
"title": "Collect business justification",
"status": "UPCOMING",
"task_category": "INTAKE_TASK",
"task_associations": [
{
"entity_id": "81",
"entity_type": "LEGAL_INTAKE",
"association_type": "PRIMARY"
}
]
}

Extract:

  • id: the task id for your own tracking

Production notes​

  • Persist the intake id from the create response and reuse it in the task, update, and delete calls.
  • Updating assignees can also change the collaborator list returned by the API.

3. Update the intake assignees​

The intake API supports partial updates. Send only the fields you want to change. When you send assignees, treat it as the desired current list.

updated_intake = requests.patch(
f"{base_url}/api/v1/public/legal_intake/{legal_intake_id}/",
headers=headers,
json={
"assignees": [
{
"entity_id": org_user_id,
"entity_type": "ORG_USER",
"assignee_type": "ASSIGNED_TO",
},
{
"entity_id": os.environ["SPOTDRAFT_COLLABORATOR_ID"],
"entity_type": "ORG_USER",
"assignee_type": "COLLABORATOR",
},
],
"priority": "HIGH",
"status": "IN_PROGRESS",
},
timeout=30,
).json()

Example response excerpt:

{
"id": 81,
"status": "IN_PROGRESS",
"priority": "HIGH",
"assignees": [
{
"entity_id": "789",
"entity_type": "ORG_USER",
"assignee_type": "ASSIGNED_TO"
}
],
"collaborators": [
{
"entity_id": "999",
"entity_type": "ORG_USER",
"assignee_type": "COLLABORATOR"
}
]
}

4. Delete the intake when it is no longer needed​

requests.delete(
f"{base_url}/api/v1/public/legal_intake/{legal_intake_id}/",
headers=headers,
timeout=30,
).raise_for_status()

Successful deletion returns 204 No Content.

Important limitation​

The public API exposes POST /api/v2.1/public/user_tasks/ for task creation, but no public PATCH, PUT, or DELETE routes for user_tasks.

That means:

  • set task assignees at creation time
  • manage intake assignees through the legal intake PATCH endpoint
  • task reassignment and task deletion aren’t available as public API operations today

Common failure points​

  • invalid intake workflow workflow_id must resolve to a published frozen workflow of type INTAKE_WORKFLOW.

  • malformed intake assignee rows Each intake assignee row must include entity_id, entity_type, and assignee_type.

  • malformed task assignee rows Each task assignee must set exactly one of org_user_id or role_id.

  • invalid intake task payload priority and intake_task_status are only valid for INTAKE_TASK.

  • 403 on intake update or delete The public intake routes intentionally return 403 when the intake is not visible in the current workspace or the caller lacks access.

  • Read Developer Settings for how teams typically discover org users and validate workflow setup.
  • Read Platform 101 for broader public API conventions.