POST /api/link/status

Last updated 2 September 2026.

POST/api/link/status
Is this subject linked, and if so, what are they shown from the directory. Optionally carries what you hold about them. Call it when you render the connection, not on a timer. Values are written before the answer is computed, so a correction you send is reflected in the same response.

Request

FieldTypeRules
subjectstringrequiredSee the subject rules.
subjectLabelstring | nulloptionalThree states: omitted leaves your stored label alone; null or "" clears it; a string sets it. Omit it when your own lookup failed.
valuesobject | nulloptionalFields you feed. Omitted or null = “I did not look”, nothing happens. Per field: null retracts your claim; a string is the value; club is an object. See below.
POST /api/link/status
Authorization: Bearer sk_yourservice_…
Content-Type: application/json

{
  "subject": "u_8f31c2",
  "subjectLabel": "ThePretorians",
  "values": {
    "club": {
      "id": "b3c1a708",
      "name": "ThePretorians",
      "slug": "thepretorians",
      "sr": 1678,
      "rank": 4,
      "wins": 395,
      "losses": 253,
      "matchesPlayed": 648
    },
    "playstation": "Coach_77",
    "xbox": null
  }
}

values.club is an allow-list of exactly these keys; anything else is a 400.

KeyTypeBound
idstringrequired; 1–255 chars, no control characters
namestring | null≤100 after whitespace collapse; blank → null
slugstring | null≤255; blank → null
srinteger | null0–10 000
rankinteger | null0–100
winsinteger | null0–10 000 000
lossesinteger | null0–10 000 000
matchesPlayedinteger | null0–10 000 000

Responses

200Not linked. Also the answer for a subject that was unlinked, or that belongs to another service — these are not distinguished.
{ "linked": false }
200Linked.
{
  "linked": true,
  "trivelaUserId": "7c0e…",
  "handle": "coach",                                  // string | null
  "linkedAt": "2026-09-02T09:03:17.000Z",

  "connections": [                                    // every OTHER live link, oldest first; may be empty
    { "service": "gpl", "name": "GOALS Pro League", "label": "coach", "linkedAt": "2026-08-14T18:20:05.000Z" }
  ],

  "shared": {                                         // frozen at these three keys; fill-if-empty
    "nationality": { "state": "synced", "value": "se" },
    "platform":    { "state": "off" },
    "club":        { "state": "synced", "value": "b3c1a708",
                     "payload": { "clubId": "b3c1a708", "name": "ThePretorians", "slug": "thepretorians",
                                  "sr": 1678, "rank": 4, "wins": 395, "losses": 253, "matchesPlayed": 648 } }
  },

  "sync": {                                           // the fields YOUR registration receives; overlay
    "avatar":      { "state": "overlay", "value": "https://cdn.discordapp.com/avatars/…/….png" },
    "handle":      { "state": "overlay", "value": "coach" },
    "playstation": { "state": "none" }
  }
}

A field you feed never appears in shared. The payload appears only beside a synced/overlay club whose id matches value. No source is ever included.

Blockstatevalue?Meaning
sharedsyncedyesApply where you hold nothing.
offnoApply nothing. Sharing is off, you are not a target, or it came from you.
conflictnoApply nothing. Two sources disagree; the player has not chosen.
emptynoApply nothing. Nobody has reported one.
syncoverlayyesShow over your own, in a separate column.
nonenoClear the overlay column. The player's own value reappears.
400A field failed validation. The whole request is rejected; nothing is applied.
{ "error": "subject …" }                                          // any subject rule
{ "error": "subjectLabel …" }                                     // any label rule
{ "error": "values must be an object when supplied." }
{ "error": "values.<field> is not a field this hub carries." }
{ "error": "values.<field> is not a field yourservice reports." } // you are not registered as its source
{ "error": "values.<field> must be a string or null." }
{ "error": "values.<field> must not be empty; send null instead." }
{ "error": "values.<field>: <the field's shape rule>" }
{ "error": "values.club must be an object or null." }
{ "error": "values.club.<key> is not a field this hub relays." }
{ "error": "values.club.id must be a non-empty string." }
{ "error": "values.club.id is not a usable identifier." }
{ "error": "values.club.<key> must be a string or null." }
{ "error": "values.club.<key> must not contain control characters." }
{ "error": "values.club.<key> must be at most <n> characters." }
{ "error": "values.club.<key> must be a whole number or null." }
{ "error": "values.club.<key> must be between 0 and <n>." }

Render a 400 as “could not reach Trivela” and keep your cached link. It is not a disconnect.

401Bad or missing key.
{ "error": "Unknown or missing service key." }

Side effects

If a reported value actually moved a shared value, Trivela pings the webhooks of the player’s other linked services after responding. Re-reporting an unchanged value does not.