Runlog docs

Start building

A plan buys a weekly allowance, sized for steady work.

Start

Channels

For data that lives in an outside account: Gmail and Microsoft 365 mailboxes and calendars, LinkedIn, Google Drive and OneDrive / SharePoint, Microsoft Copilot, and the social surfaces. Connecting one is a consent step that happens in the provider's own browser flow; everything after it is API-reachable, and synced content becomes ordinary corpus. The routes at the top are the same for every provider; the sections below them are what only a file store or Copilot can do here. What a channel SENDS lives in the Execution leg's Outbound lane, where the approval gate is the story.

GET/v1/user/channelsSession

List connected channels

Read which channels are connected, their health, and when each last synced.

A channel that has fallen out of authorization reports it here rather than failing silently on the next sync — check this before concluding a sync returned nothing because there was nothing.

Request · curl
curl -X GET "https://runlog-7613480744.us-central1.run.app/v1/user/channels" \
  -H "Authorization: Bearer $RUNLOG_SESSION_TOKEN" \
  -H "X-Project-Id: p7Kd2mQx"
Response · 200
{
  "channels": [
    {
      "account": "amber@example.com",
      "channelId": "ch_6Wr4Bn",
      "kind": "email",
      "lastSyncedAt": "2026-08-07T18:31:44Z",
      "status": "connected"
    }
  ]
}

Errors

StatuserrorWhen
401unauthorizedNo valid session.
POST/v1/channelsSession

Begin a connection

Start a channel connection and receive the consent link to send the account holder to.

Connection cannot be completed by API, by design: the account holder authorizes it in their own provider's browser flow. This route returns the link; the connection lands when they finish it.

A connection needing a second factor pauses at a checkpoint, which the same lane resolves once the holder supplies it.

Body

FieldTypeRequiredDescription
actionstringrequired`connect-link` for the hosted flow, `reconnect-link` to re-authorize an existing channel.
kindstringrequiredThe channel kind to connect: `email`, `calendar`, `professional-network`, `store`, `social`.
providerstringoptionalWhich account within the kind: `gmail`, `microsoft-365`, `linkedin`, `google-drive`, `onedrive`, `meta`, `tiktok`. Defaults to the only provider serving that kind.
Request · curl
curl -X POST "https://runlog-7613480744.us-central1.run.app/v1/channels" \
  -H "Authorization: Bearer $RUNLOG_SESSION_TOKEN" \
  -H "X-Project-Id: p7Kd2mQx" \
  -H "Content-Type: application/json" \
  -d '{
  "action": "connect-link",
  "kind": "email",
  "provider": "gmail"
}'
Response · 200
{
  "expiresAt": "2026-08-07T19:00:00Z",
  "url": "https://connect.runlogai.com/…"
}

Errors

StatuserrorWhen
400invalid request bodyThe body is not JSON, or exceeds the 1 MB request-body cap.
401invalid API keyThe `Authorization` header is missing, malformed, or names a revoked key.
400name the target project via the X-Project-Id header or projectId queryNo project was named and the key is not bound to one.
429rate limit exceededYou passed 60 requests/minute on this key. `Retry-After` carries the seconds to wait.
500internal errorThe relay failed to serve the request. Retry with backoff; the cause is logged server-side against your request.
POST/v1/channel-sync/{channelId}API key

Sync a channel

Pull the channel's history into the project's corpus, where retrieval reaches it.

Incremental after the first run: a sync resumes from its own watermark, so calling it repeatedly is cheap and calling it twice is not a duplicate.

Synced content becomes ordinary corpus. A question about what a customer said in an email is answered by the same retrieval that answers a question about a file.

Path parameters

FieldTypeRequiredDescription
channelIdstringrequiredThe connected channel to sync.
Request · curl
curl -X POST "https://runlog-7613480744.us-central1.run.app/v1/channel-sync/ch_6Wr4Bn" \
  -H "Authorization: Bearer $RUNLOG_API_KEY" \
  -H "X-Project-Id: p7Kd2mQx" \
  -H "Content-Type: application/json" \
  -d '{}'
Response · 202
{
  "channelId": "ch_6Wr4Bn",
  "queued": true,
  "since": "2026-08-06T00:00:00Z"
}

Errors

StatuserrorWhen
404channel not foundNo such channel, or it is not yours.
409channel needs reauthorizationThe connection has lapsed. Send the holder a `reconnect-link` before syncing again.
401invalid API keyThe `Authorization` header is missing, malformed, or names a revoked key.
400name the target project via the X-Project-Id header or projectId queryNo project was named and the key is not bound to one.
429rate limit exceededYou passed 60 requests/minute on this key. `Retry-After` carries the seconds to wait.
500internal errorThe relay failed to serve the request. Retry with backoff; the cause is logged server-side against your request.