API reference

Mentions

4 endpoints, served at https://orbitwrite.com/api/v1. Each one lists the credentials it accepts, its parameters and every response it can give.

Search a platform for accounts to @mention#

GET/api/v1/mentions/handles

Requires account:read. Type-ahead over the platforms whose mentions are plain handles — X, Bluesky and Mastodon. Insert the returned handle after an @ in the post body and the platform resolves it at publish time; no id or markup is needed. The workspace's own directory answers first (its channels, handles remembered from earlier picks, people from the inbox, @handles in its posts), then the network: Bluesky's and Mastodon's own search, or for X an exact lookup of the whole query as a handle — X has no affordable name search, so on X a partial name only matches people the workspace already knows. Mastodon handles are returned qualified (user@instance). A Mastodon search runs against that account's own instance on its token, so two channels can return different results for the same query. Channels on other platforms are a 400 — Threads has no handle search, and LinkedIn mentions are structured nodes (use /mentions/linkedin). A Bluesky or Mastodon search that can't reach the network is a 502; an X lookup that fails or is out of budget just adds nothing.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Query parameters

accountIdstringRequired

The connected channel the mention is being written for. Names the workspace, and on Mastodon supplies the instance and token the search runs against.

At least 1 character.

qstringRequired

What the author has typed after the @.

Between 1 and 200 characters.

Responses

200object

Matching accounts, best first, capped at 8

Response attributes
resultsHandleMention[]Required
Child attributes
handlestringRequired

Inserted verbatim after @. A username on X (jack), a domain on Bluesky (alice.bsky.social), user@instance on Mastodon.

avatarUrlstring
sourcestring

Where the candidate came from. channel: one of the workspace's own accounts. remembered: picked from this typeahead before (see POST /mentions/remembered). inbox: someone who replied to or mentioned the workspace. recent: an @handle in one of the workspace's posts on this network. search: the network's own typeahead (Bluesky, Mastodon). lookup: X's exact match for the whole query, at most one, appended last. The first four are the workspace's own data.

  • "channel"
  • "remembered"
  • "inbox"
  • "recent"
  • "search"
  • "lookup"
contactIdstring

The directory contact this handle belongs to, when an author has linked it to handles on other networks.

identitiesobject[]

The same person's handles on other networks, as linked by an author. Omitted when there are none.

Child attributes
platformstringRequired
handlestringRequired
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
429Error

Rate limit exceeded

Response attributes
errorstringRequired
issuesany[]
502object

The platform couldn't be reached

Response attributes
errorstringRequired
GET /api/v1/mentions/handles
curl -X GET "https://orbitwrite.com/api/v1/mentions/handles?accountId=accountId&q=q" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "results": [
    {
      "handle": "string",
      "displayName": "string",
      "avatarUrl": "string",
      "source": "channel",
      "contactId": "string",
      "identities": [
        {
          "platform": "string",
          "handle": "string",
          "displayName": "string"
        }
      ]
    }
  ]
}

Resolve a LinkedIn company slug to its organization URN#

GET/api/v1/mentions/linkedin/resolve

Requires account:read. Turns the vanity name in a company URL (linkedin.com/company/orbitwrite → orbitwrite) into the urn:li:organization:… a LinkedIn mention node needs, asking LinkedIn with the named channel's token. The lookup is exact-match: a slug LinkedIn has no company for returns { "organization": null }, which is an answer and not an error — fall back to a numeric company URL or a URN the author supplies. A 502 means the lookup itself failed and the slug is still unknown; do not write a mention on the strength of one.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Query parameters

accountIdstringRequired

The connected channel the mention is being written for. Names the workspace, and on Mastodon supplies the instance and token the search runs against.

At least 1 character.

slugstringRequired

The vanity name from the company URL, without the leading path.

Between 1 and 100 characters.

Responses

200object

The organization, or null when LinkedIn has no company with that vanity name

Response attributes
organizationobject | any | nullRequired
Child attributes
urnstringRequired
urlstringRequired
namestring
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
429Error

Rate limit exceeded

Response attributes
errorstringRequired
issuesany[]
502object

LinkedIn couldn't be reached

Response attributes
errorstringRequired
GET /api/v1/mentions/linkedin/resolve
curl -X GET "https://orbitwrite.com/api/v1/mentions/linkedin/resolve?accountId=accountId&slug=slug" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "organization": {
    "urn": "string",
    "url": "string",
    "name": "string"
  }
}

Search LinkedIn mention candidates#

GET/api/v1/mentions/linkedin

Requires account:read. LinkedIn mentions are structured URN nodes rather than plain handles, so build the mention from the returned id — there is nothing useful to type.

Four directories, distinguished by source. channel results are the workspace's own connected LinkedIn accounts, substring-matched. recent results are people and companies the workspace has already @mentioned in LinkedIn posts written through Orbitwrite (never imported ones), most-used first. follower results are members who follow one of the workspace's Pages, found by LinkedIn's People Typeahead: from a Page channel, that Page's followers; from a personal channel, the followers of up to two of the workspace's Pages. Only Pages whose connection granted r_organization_followers are asked (reconnect a Page connected before Orbitwrite asked for it), and only for queries in LinkedIn's grammar — letters plus at most one space and single ', - or ., at least 3 characters (6 with a space or dot). LinkedIn returns only followers who allow mentions. A lookup result is a company LinkedIn itself returned, and appears only when the whole query is a well-formed vanity name — their keyword company search is restricted to selected developers, so exact match on the vanity name is the only search available to us. Typing orbit will not find orbitwrite; typing orbitwrite will. Queries shorter than 3 characters never reach LinkedIn, and a client should debounce: the quota behind this is per application per day, not per caller, so every prefix you send costs everyone.

A LinkedIn that can't be reached costs you the follower and lookup candidates, not the request. LinkedIn offers no search over a member's connections, so a personal channel finds people only through the workspace's own channels, its earlier mentions and its Pages' followers.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Query parameters

accountIdstringRequired

The connected channel the mention is being written for. Names the workspace, and on Mastodon supplies the instance and token the search runs against.

At least 1 character.

qstringRequired

What the author has typed after the @.

Between 1 and 200 characters.

Responses

200object

Matching mention targets, capped at 8 in total — a lookup result displaces the last channel rather than extending the list.

Response attributes
resultsLinkedInMention[]Required
Child attributes
idstringRequired

The URN to address: urn:li:organization:123 for a page, urn:li:person:<sub> for a person.

namestringRequired
avatarUrlstring
typestringRequired
  • "person"
  • "organization"
headlinestring

The member's LinkedIn headline, follower results only — what tells two people with the same name apart. Followers carry no photo.

sourcestringRequired

channel is a LinkedIn account connected to this workspace, substring-matched. recent is a person or company this workspace has already @mentioned in a LinkedIn post written through Orbitwrite, substring-matched on the label last used. follower is a member who follows one of the workspace's Pages, prefix-matched on first or last name by LinkedIn. lookup is a company LinkedIn returned for the query taken as a vanity name — at most one, only when the query is a complete vanity name. Don't blend the two in a UI: a lookup row appears only on the last keystroke, which reads as a glitch inside a list that has been filtering all along.

  • "channel"
  • "recent"
  • "follower"
  • "lookup"
urlstring

Canonical linkedin.com URL, organizations only. Cross-posting a mention to a non-LinkedIn network degrades to this link; people have no equivalent public URL derivable from the URN.

400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
429Error

Rate limit exceeded

Response attributes
errorstringRequired
issuesany[]
GET /api/v1/mentions/linkedin
curl -X GET "https://orbitwrite.com/api/v1/mentions/linkedin?accountId=accountId&q=q" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "results": [
    {
      "id": "string",
      "name": "string",
      "avatarUrl": "string",
      "type": "person",
      "headline": "string",
      "source": "channel",
      "url": "string"
    }
  ]
}

Remember a handle for the mention typeahead#

POST/api/v1/mentions/remembered

Requires post:create. Adds a handle to the workspace's mention directory, or counts another use of one already there, so GET /mentions/handles offers it to everyone in the workspace from then on without asking the network. accountId is the X, Bluesky or Mastodon channel the mention is written from: it names the network, and a bare Mastodon username is qualified with that channel's instance. The handle must be well-formed for the network (a leading @ is ignored). displayName and avatarUrl are optional, and when omitted the stored ones are kept; avatarUrl must be https.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Body application/json

accountIdstringRequired

At least 1 character.

handlestringRequired

Between 1 and 300 characters.

displayNamestring

At most 200 characters.

avatarUrlstring

At most 2000 characters. Format uri.

Responses

200object

The directory entry as stored, with source: "remembered"

Response attributes
mentionHandleMentionRequired
Child attributes
handlestringRequired

Inserted verbatim after @. A username on X (jack), a domain on Bluesky (alice.bsky.social), user@instance on Mastodon.

avatarUrlstring
sourcestring

Where the candidate came from. channel: one of the workspace's own accounts. remembered: picked from this typeahead before (see POST /mentions/remembered). inbox: someone who replied to or mentioned the workspace. recent: an @handle in one of the workspace's posts on this network. search: the network's own typeahead (Bluesky, Mastodon). lookup: X's exact match for the whole query, at most one, appended last. The first four are the workspace's own data.

  • "channel"
  • "remembered"
  • "inbox"
  • "recent"
  • "search"
  • "lookup"
contactIdstring

The directory contact this handle belongs to, when an author has linked it to handles on other networks.

identitiesobject[]

The same person's handles on other networks, as linked by an author. Omitted when there are none.

Child attributes
platformstringRequired
handlestringRequired
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
429Error

Rate limit exceeded

Response attributes
errorstringRequired
issuesany[]
POST /api/v1/mentions/remembered
curl -X POST "https://orbitwrite.com/api/v1/mentions/remembered" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "accountId": "string",
  "handle": "string"
}'
Response
{
  "mention": {
    "handle": "string",
    "displayName": "string",
    "avatarUrl": "string",
    "source": "channel",
    "contactId": "string",
    "identities": [
      {
        "platform": "string",
        "handle": "string",
        "displayName": "string"
      }
    ]
  }
}