Help center

Assign an SOP

Reference for POST /assignments, which assigns an SOP to a member by sign-in email, refuses duplicates and sends no email.

Business plan Updated
On this page
  1. Body parameters
  2. Behavior
  3. Request
  4. Response
  5. Errors
Shell
POST https://app.sopcompass.com/api/v1/assignments

Scope: read and write. Content-Type: application/json.

Assigns an SOP to a member of the workspace, by their sign-in email. Returns 201 Created with the new assignment, shaped as in List assignments.

Important: The API does not send the assignment email the app sends. The assignment appears in the person’s Assignments in the app, but nobody is notified. If people should hear about it, notify them your own way, for example from the same Zap or script.

Body parameters

Name Type Required Description
sop_id UUID Yes An SOP the workspace can see (its own or in a shared-in library) that isn’t archived.
email string Yes The member’s sign-in email. Not case sensitive; surrounding spaces are ignored.
due_on string or null No Due date as YYYY-MM-DD. Must be a real calendar date. A date in the past is accepted, and the assignment is then overdue straight away.
note string or null No A note for the assignee, up to 1,000 characters. A blank note is stored as null.

Behavior

  • Recorded as assigned by the key’s creator. assigned_by is the owner or admin who created the API key.
  • No duplicates. If the person already has this SOP assigned and not yet completed (from the app or the API), the request is refused with 422 already_assigned. A retried request therefore never assigns twice. Once they complete it, it can be assigned again.
  • Members only. Someone who hasn’t joined the workspace yet gets 422 not_a_member. Invite them in the app first; use GET /people to check.
  • No email. See the note above.

Request

Shell
curl https://app.sopcompass.com/api/v1/assignments \
  -H "Authorization: Bearer $SOPCOMPASS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sop_id": "5b7e9d1a-2c4f-4e6b-8a1d-3c5e7f9a0b03",
    "email": "new.cleaner@example.com",
    "due_on": "2026-10-01",
    "note": "Please finish before your first shift."
  }'
JavaScript
const res = await fetch("https://app.sopcompass.com/api/v1/assignments", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SOPCOMPASS_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sop_id: "5b7e9d1a-2c4f-4e6b-8a1d-3c5e7f9a0b03",
    email: "new.cleaner@example.com",
    due_on: "2026-10-01",
    note: "Please finish before your first shift.",
  }),
});

const body = await res.json();
if (res.status === 201) {
  console.log("Assigned", body.data.id);
} else if (body.error.code === "already_assigned") {
  console.log("Already assigned, nothing to do");
} else {
  throw new Error(`${res.status} ${body.error.code}: ${body.error.message}`);
}
Python
import os
import requests

res = requests.post(
    "https://app.sopcompass.com/api/v1/assignments",
    headers={"Authorization": f"Bearer {os.environ['SOPCOMPASS_API_KEY']}"},
    json={
        "sop_id": "5b7e9d1a-2c4f-4e6b-8a1d-3c5e7f9a0b03",
        "email": "new.cleaner@example.com",
        "due_on": "2026-10-01",
        "note": "Please finish before your first shift.",
    },
    timeout=30,
)
body = res.json()
if res.status_code == 201:
    print("Assigned", body["data"]["id"])
elif body["error"]["code"] == "already_assigned":
    print("Already assigned, nothing to do")
else:
    raise RuntimeError(f"{res.status_code} {body['error']['code']}: {body['error']['message']}")

Response

201 Created

JSON
{
  "data": {
    "id": "d5f7b9c1-3e5a-4f7b-9d1e-3f5a7c9e1b23",
    "sop": {
      "id": "5b7e9d1a-2c4f-4e6b-8a1d-3c5e7f9a0b03",
      "title": "New hire onboarding"
    },
    "assignee": {
      "id": "2c4e6a8b-0d2f-4e4a-8b6c-8d0f2a4c6e22",
      "name": null,
      "email": "new.cleaner@example.com"
    },
    "assigned_by": {
      "id": "8e0a2c4d-6f8b-4a0c-8e2d-4f6a8c0e2a09",
      "name": "Dana Whitfield",
      "email": "dana.whitfield@example.com"
    },
    "note": "Please finish before your first shift.",
    "due_on": "2026-10-01",
    "requires_quiz": false,
    "status": "open",
    "viewed_at": null,
    "completed_at": null,
    "created_at": "2026-09-19T16:20:41.873506Z"
  }
}

Errors

Status Code When
400 invalid_json The body isn’t a JSON object.
403 read_only_key The key is read only.
403 workspace_read_only The workspace’s subscription has ended.
404 not_found No SOP with that id is visible to this workspace.
415 unsupported_media_type The request has no Content-Type: application/json header.
422 invalid_parameter sop_id is missing or not a UUID, email is missing or doesn’t look like an email address, or due_on isn’t a real YYYY-MM-DD date.
422 invalid_note note isn’t a string, or is longer than 1,000 characters.
422 sop_archived The SOP is archived. Restore it in the app first.
422 not_a_member Nobody in the workspace signs in with that email.
422 already_assigned The person already has this SOP assigned and not yet completed.

Authentication, plan and rate limit errors apply to every endpoint; see Errors.