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 current public API exposes POST /api/v2.1/public/user_tasks/ for task creation, but it does not expose public PATCH, PUT, or DELETE routes for user_tasks.

That means:

  • set task assignees at creation time
  • update intake assignees through the legal intake PATCH endpoint
  • do not document task reassignment or task deletion as public API operations unless those routes are added to the public schema later

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.