Assignments

A badge is not a person. It is lent, returned, reassigned — and every one of those moves has a date. An assignment records which subject a credential belonged to over which period, so a badge handed to someone new next month leaves last month's reports exactly as they were.

The assignment model

Properties

  • Name
    credential
    Type
    string
    Description

    Required. The external_id of the credential — the badge, tag or card.

  • Name
    subject
    Type
    string
    Description

    Required. The external_id of the subject it belongs to.

  • Name
    valid_from
    Type
    string
    Description

    Required. ISO 8601, when the binding starts. Always give a UTC offset (+01:00, Z): the API does not refuse a value without one, but cannot know which zone you meant. The SDKs refuse it before sending.

  • Name
    valid_to
    Type
    string
    Description

    Optional, same format. Omitted means still valid — the common case for a badge currently in someone's pocket. Must be after valid_from.

  • Name
    relation
    Type
    string
    Description

    Optional, defaults to assigned_to. What kind of binding this is.


POST/v1/assignments

Create assignments

Create, close or hand over up to 500 credential-to-subject bindings — a line sent again is read against what the badge already has (Reassigning a badge). Both entities are created undeclared if they do not exist yet — the same tolerance as everywhere else in the reference.

Required attributes

  • Name
    assignments
    Type
    array
    Description

    Up to 500 assignments.

Headers

  • Name
    Authorization
    Type
    string
    Description

    Bearer <api_key>.

Rejection codes

  • Name
    invalid_validity_period
    Type
    code
    Description

    valid_from or valid_to is not a date-time, or valid_to is not after valid_from.

  • Name
    overlapping_assignment
    Type
    code
    Description

    This credential already has an assignment covering part of that window. Never merged silently — you decide which one is right.

Request

POST
/v1/assignments
curl https://api.sinio.ai/v1/assignments \
  -H "Authorization: Bearer $SINIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "assignments": [
      {
        "credential": "04A2B9C1",
        "subject": "P-4582",
        "relation": "assigned_to",
        "valid_from": "2026-01-01T00:00:00+01:00"
      }
    ]
  }'

Response

{
  "accepted": 1,
  "rejected": 0,
  "rejections": []
}

Overlap rejected

{
  "accepted": 0,
  "rejected": 1,
  "rejections": [
    {
      "credential": "04A2B9C1",
      "subject": "P-7781",
      "code": "overlapping_assignment",
      "message": "This credential already has an overlapping assignment"
    }
  ]
}

Reassigning a badge

Send the list as your HR system holds it, as often as you like. POST /v1/assignments reads each line against what the badge already has:

  • The same credential, subject and valid_from is the same assignment. Sent again unchanged, nothing happens; sent with a valid_to, it is closed; sent without one, it is open again. So the end date can come in a later replay, once you know it.
  • A new subject for the badge closes the assignment still open at the new valid_from, then opens the new one. Handing a badge over is a single line.
  • Anything else that overlaps an existing window is rejected as overlapping_assignment, line by line.

Month 1: the badge is in P-4582’s pocket

{
  "assignments": [
    { "credential": "04A2B9C1", "subject": "P-4582", "valid_from": "2026-01-01T00:00:00+01:00" }
  ]
}

Month 9: handed over — P-4582’s assignment ends where P-7781’s begins

{
  "assignments": [
    { "credential": "04A2B9C1", "subject": "P-4582", "valid_from": "2026-01-01T00:00:00+01:00", "valid_to": "2026-09-01T00:00:00+02:00" },
    { "credential": "04A2B9C1", "subject": "P-7781", "valid_from": "2026-09-01T00:00:00+02:00" }
  ]
}

The second line alone would do the same: P-4582's open assignment ends at P-7781's start. The window is half-open — valid_to is excluded — so one binding ending at the exact instant the next one starts is not an overlap.

Historical reports keep pointing at the subject who actually held the badge at the time. That is the entire reason assignments carry dates instead of being a simple foreign key.

Was this page helpful?