Back to partner brief

Engineering handoff

Linq integration guide

Tier 1–3 wiring, API contracts, credentials, and pilot runbook. API base: https://api.rora.carmel.so

Start here

Linq engineering — Tier 1 first.

Immediate next steps

  1. Align on the product: reliability toggle in Linq → Agent Status probes → reliability field in Linq UI (no AS signup at toggle)
  2. Agree pilot scope: sandbox bearer + locators; second owned line or reply bot if inbound UP is in scope
  3. Then wire Tier 1: POST …/webhooks/monitoring (we share LINQ_WEBHOOK_SECRET when Linq is ready to integrate)
  4. Render response.reliability in Linq partner UI; poll GET …/registration / status as fallback

Linq users should not create Agent Status accounts at toggle time. Implement tiers in order: Tier 1 first, then add Tier 2 links, then Tier 3 for power users. Checklists show a progress bar plus Done / Todo badges for each item.

Integration tiers

Tier 1 → 2 → 3.

Tier 1

Agent Status shipped — waiting on Linq wiring

Reliability field in Linq (no Agent Status login)

Partner toggles “Enable reliability monitoring” in Linq. Linq fires webhook; Agent Status starts Linq v3 probes (send → delivery poll → optional inbound). Linq polls status API and renders verdict + uptime. User never leaves Linq.

Linq — todos

0 / 6 done
  • TodoAdd toggle on agent/line publish: “Enable reliability monitoring”
  • TodoOn save → POST …/webhooks/monitoring (event: monitoring.enabled, enable_monitoring: true)
  • TodoPass authorization (Bearer), from/to or chat_id, external_id for locator
  • TodoFallback: poll GET …/registration until monitoring_state = active
  • TodoPoll GET …/status every 1–5 min → copy response.reliability into partner UI
  • TodoConfirm sandbox bearer + 5–10 pilot locators

Agent Status — todos

5 / 5 done
  • DoneWebhook onboard + monitoring.disabled pause
  • DoneRegistration + status APIs with reliability block
  • DoneLinq adapter (request_format=linq) on residential nodes
  • DonePortfolio defaults: expect_inbound=true, gate_on_chat_health=false
  • DoneLive on api.rora.carmel.so; secrets generated — share with Linq only after Tier 1 go-ahead

APIs

  • POST https://api.rora.carmel.so/api/partner/linq/webhooks/monitoring
  • GET https://api.rora.carmel.so/api/partner/linq/agents/{locator}/registration
  • GET https://api.rora.carmel.so/api/partner/linq/agents/{locator}/status

reliability field (copy into Linq partner UI)

{
  "provider": "agentstatus.dev",
  "monitoring": "active",
  "verdict": "UP",
  "status": "operational",
  "uptime_pct": 98.2,
  "pass_rate": 0.94,
  "last_checked_at": "2026-08-02T17:30:00Z",
  "reliability_label": "Operational",
  "report_url": "https://agentstatus.dev/linq/status?locator=...",
  "badge_url": "https://api.rora.carmel.so/.../badge.svg",
  "claim_url": "https://agentstatus.dev/linq/claim?token=..."
}

Tier 2

Agent Status shipped — Linq adds links

Public report + badge embed

Linq shows “View full report” (report_url) and optional SVG badge. User opens read-only report — no login.

Linq — todos

0 / 2 done
  • TodoAdd link: reliability.report_url → “View full report”
  • TodoOptional: <img src="reliability.badge_url"> in agent detail

Agent Status — todos

3 / 3 done
  • DonePublic report page: agentstatus.dev/linq/status?locator={locator}
  • DonePublic status API: GET …/status/public (no auth)
  • DoneSVG badge: GET …/badge.svg

APIs

  • GET https://api.rora.carmel.so/api/partner/linq/agents/{locator}/status/public
  • GET https://api.rora.carmel.so/api/partner/linq/agents/{locator}/badge.svg
  • https://agentstatus.dev/linq/status?locator={locator}

Tier 3

Agent Status shipped — Linq adds claim_url link

Full dashboard — opt-in

Power users click claim_url → validate token → open dashboard for alerts, drift, studio. Not required at toggle time.

Linq — todos

0 / 3 done
  • TodoAdd link: reliability.claim_url → “Manage alerts & metrics”
  • TodoPass owner_email in webhook when available
  • TodoDo not require Agent Status signup at toggle time

Agent Status — todos

5 / 5 done
  • DoneClaim token issued on webhook create (30-day expiry)
  • DoneGET …/claim/{token} — validate + dashboard URLs
  • DoneClaim landing: agentstatus.dev/linq/claim?token=…
  • DonePOST …/claim/{token}/redeem + GET …/start magic handoff
  • DoneAuto-attach on signup/verify via linq_claim_token

APIs

  • claim_url in webhook + status responses
  • GET https://api.rora.carmel.so/api/partner/linq/claim/{token}
  • POST https://api.rora.carmel.so/api/partner/linq/claim/{token}/redeem
  • https://agentstatus.dev/linq/claim?token={token}
  • https://platform.agentstatus.dev/rora/agents/{agent_id}

Credentials — who generates what

ItemGenerated byShared withTierNotes
LINQ_WEBHOOK_SECRETAgent StatusLinqTier 1HMAC secret — Linq signs webhook body: X-Linq-Signature: sha256=…
LINQ_STATUS_API_TOKENAgent StatusLinqTier 1Read token — header X-Linq-Api-Token on registration + status polls.
Linq Partner API bearerLinq (sandbox)Agent Status (probe auth)Tier 1Passed in webhook authorization field; stored encrypted for residential probes.
Pilot locators (5–10)LinqAgent StatusTier 1linq:{external_id} locators with live sandbox lines.

Quick curl — webhook + status poll

# Tier 1 — enable monitoring (replace SECRET; authorization = Linq Partner API bearer)
BODY='{"event":"monitoring.enabled","locator":"linq:sandbox-pilot-demo","enable_monitoring":true,"external_id":"sandbox-pilot-demo","display_name":"Sandbox Pilot Agent","authorization":"Bearer $LINQ_PARTNER_TOKEN","from":"+15551234567","to":["+15559876543"]}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$LINQ_WEBHOOK_SECRET" | awk '{print $2}')

curl -sS -w "\nHTTP %{http_code}\n" -X POST "https://api.rora.carmel.so/api/partner/linq/webhooks/monitoring" \
  -H "Content-Type: application/json" \
  -H "X-Linq-Signature: sha256=$SIG" \
  -d "$BODY" | jq .
curl -sS -w "\nHTTP %{http_code}\n" \
  "https://api.rora.carmel.so/api/partner/linq/agents/linq:sandbox-pilot-demo/status" \
  -H "X-Linq-Api-Token: $LINQ_STATUS_API_TOKEN" | jq .

Probe flow

Linq v3 — residential outside-in.

Confirmed against sandbox using linq:sandbox-pilot-demo. Probes run on 2,500+ residential Fabric nodes — send, delivery poll, optional inbound reply.

1

Linq Partner API — create chat / send

POST https://api.linqapp.com/api/partner/v3/chats

Authorization: Bearer <linq_partner_token>

{
  "from": "+15551234567",
  "to": ["+15559876543"],
  "message": { "parts": [{ "type": "text", "value": "ping" }] }
}

Agent Status residential nodes call Linq v3 from consumer networks — not from our API server.

2

Delivery poll

GET https://api.linqapp.com/api/partner/v3/chats/{chat_id}/messages/{message_id}

{
  "id": "...",
  "delivery_status": "delivered",
  "parts": [{ "type": "text", "value": "..." }]
}

Verdict aggregates send success, delivery state, and optional inbound reply across 2,500+ nodes.

3

Optional inbound (expect_inbound=true)

GET https://api.linqapp.com/api/partner/v3/chats/{chat_id}/messages?direction=inbound

{
  "messages": [{ "direction": "inbound", "parts": [...] }]
}

Pilot default: expect_inbound=true, gate_on_chat_health=false.

Partner APIs

Agent Status endpoints.

Monitoring webhook (Tier 1)

Linq → Agent Status

POST https://api.rora.carmel.so/api/partner/linq/webhooks/monitoring

X-Linq-Signature: sha256=<hmac-sha256-hex of raw body>

{
  "event": "monitoring.enabled",
  "locator": "linq:sandbox-pilot-demo",
  "enable_monitoring": true,
  "external_id": "sandbox-pilot-demo",
  "display_name": "Sandbox Pilot Agent",
  "authorization": "Bearer <linq_partner_token>",
  "from": "+15551234567",
  "to": ["+15559876543"],
  "owner_email": "owner@example.com"
}

202 Accepted — creates/updates monitoring record, returns reliability + claim_url. Also supports monitoring.disabled.

Status + registration (Tier 1 poll)

Linq → Agent Status

GET https://api.rora.carmel.so/api/partner/linq/agents/{locator}/status GET https://api.rora.carmel.so/api/partner/linq/agents/{locator}/registration

X-Linq-Api-Token: <LINQ_STATUS_API_TOKEN>

// status response includes:
{
  "locator": "linq:…",
  "verdict": "UP",
  "reliability": { "provider": "agentstatus.dev", "uptime_pct": 98.2, ... }
}

Use registration as fallback when webhook times out. Poll status every 1–5 min for partner UI.

Open with Linq

  • Chat health gating — default off for pilot (gate_on_chat_health=false)
  • Inbound reply expectation — default on (expect_inbound=true) for agent surfaces
  • Production bearer rotation and scoped probe credentials

Dashboard access

Dashboard access — who sees what

Webhook onboarding (Tier 1) does not create Agent Status dashboard logins. The partner APIs are the Tier 1 surface for Linq.

AudienceAccess
Linq partner UI (Tier 1)Partner registration + status APIs only — no Agent Status login
Public visitors (Tier 2)report_url and GET …/status/public — no login
Individual agent owner (Tier 3)reliability.claim_url → signup at platform.agentstatus.dev → dashboard scoped to that one agent
Linq pilot ops (fleet view)Not automatic from the webhook. Agent Status provisions a shared pilot ops login for fleet visibility. Request access from Agent Status.

Tier 3 claim is per-agent. A separate pilot ops account is required to see the full pilot fleet in one dashboard view.

Acceptance test

Tier 1–3 E2E — how we measure success

Tier 1 is done when steps 1–5 pass on the demo locator (linq:sandbox-pilot-demo). Tier 2 adds steps 6–8 (public report + Linq links). Tier 3 adds steps 9–11 (claim → dashboard for one agent). Agent Status ships steps 1–8 and claim API live; Linq must pass partner UI wiring before Tier 2/3 are declared done.

Demo locator: linq:sandbox-pilot-demo. Tier 1: steps 1–3 · Tier 2: steps 4–8 · Tier 3: steps 9–11.

Prerequisites — Agent Status

  • Partner API live at api.rora.carmel.so
  • Webhook secret + status token shared with Linq (out of band)

Prerequisites — Linq

  • 5–10 pilot locators with sandbox Partner API bearer
  • Webhook handler with HMAC signature verification
  • Status poll or webhook fallback for registration state
1

Signed webhook — enable monitoring

Tier 1 onboarding path. Linq fires this on toggle save.

# Tier 1 — enable monitoring (replace SECRET; authorization = Linq Partner API bearer)
BODY='{"event":"monitoring.enabled","locator":"linq:sandbox-pilot-demo","enable_monitoring":true,"external_id":"sandbox-pilot-demo","display_name":"Sandbox Pilot Agent","authorization":"Bearer $LINQ_PARTNER_TOKEN","from":"+15551234567","to":["+15559876543"]}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$LINQ_WEBHOOK_SECRET" | awk '{print $2}')

curl -sS -w "\nHTTP %{http_code}\n" -X POST "https://api.rora.carmel.so/api/partner/linq/webhooks/monitoring" \
  -H "Content-Type: application/json" \
  -H "X-Linq-Signature: sha256=$SIG" \
  -d "$BODY" | jq .

Verify

  • HTTP 202 Accepted
  • Response includes agent_id and reliability block
  • reliability.claim_url present when owner_email omitted
2

Registration poll (fallback gate)

Use when webhook succeeds but UI needs explicit registration state.

curl -sS -w "\nHTTP %{http_code}\n" \
  "https://api.rora.carmel.so/api/partner/linq/agents/linq:sandbox-pilot-demo/registration" \
  -H "X-Linq-Api-Token: $LINQ_STATUS_API_TOKEN" | jq .

Verify

  • monitoring_state is registered or active
  • probe_state may be pending_first_probe until first scheduled probe (~60 min)
3

Status poll → reliability field

Copy response.reliability into Linq partner UI every 1–5 minutes.

curl -sS -w "\nHTTP %{http_code}\n" \
  "https://api.rora.carmel.so/api/partner/linq/agents/linq:sandbox-pilot-demo/status" \
  -H "X-Linq-Api-Token: $LINQ_STATUS_API_TOKEN" | jq .

Verify

  • reliability.provider = agentstatus.dev
  • reliability.verdict + reliability_label present
  • reliability.report_url and reliability.badge_url populated
4

Public status API (Tier 2 gate)

No auth — same reliability shape for public report pages.

curl -sS -w "\nHTTP %{http_code}\n" \
  "https://api.rora.carmel.so/api/partner/linq/agents/linq:sandbox-pilot-demo/status/public" | jq .reliability

Verify

  • HTTP 200 without X-Linq-Api-Token
  • reliability block matches authenticated status poll
5

Badge SVG (Tier 2 gate)

Optional embed; shows Pending until first probe completes.

curl -sS -w "\nHTTP %{http_code}\n" \
  "https://api.rora.carmel.so/api/partner/linq/agents/linq:sandbox-pilot-demo/badge.svg" \
  -o /tmp/linq-badge.svg && head -c 200 /tmp/linq-badge.svg

Verify

  • HTTP 200, Content-Type image/svg+xml
  • SVG renders verdict label (e.g. Pending, UP)
6

Public report page (Tier 2 gate)

Open reliability.report_url from step 3 in a browser — no login.

# Same URL as reliability.report_url from step 3
open "https://agentstatus.dev/linq/status?locator=linq%3Asandbox-pilot-demo"

# Smoke: public report page loads (same URL as reliability.report_url)
curl -sS -o /dev/null -w "HTTP %{http_code}\n" \
  "https://agentstatus.dev/linq/status?locator=linq%3Asandbox-pilot-demo"

Verify

  • HTTP 200
  • Page shows agent name, locator, verdict / reliability label, and last checked time
  • URL matches reliability.report_url from the status poll exactly
7

Linq — “View full report” link (Tier 2 gate)

Wire partner UI to reliability.report_url from the status poll.

{# Use reliability.report_url from status poll — do not hardcode #}
<a href="{{ reliability.report_url }}" target="_blank" rel="noopener noreferrer">
  View full report
</a>

Verify

  • “View full report” visible on the Linq agent / line surface
  • href equals reliability.report_url (not hardcoded)
  • Opens agentstatus.dev/linq/status?locator=… in a new tab
8

Linq — badge on card (Tier 2 optional)

Optional SVG badge next to the reliability field.

{# img from status poll (simplest) #}
<a href="{{ reliability.report_url }}" target="_blank" rel="noopener noreferrer">
  <img src="{{ reliability.badge_url }}" alt="Agent reliability status" height="28" />
</a>

Verify

  • Badge renders on the Linq surface (img)
  • Badge label matches current verdict
  • Clicking badge opens the same report URL as step 6
9

Claim token validate — API (Tier 3 gate)

Token comes from step 3 reliability.claim_url.

# Copy token from reliability.claim_url — URL ends with ?token=…
TOKEN="{claim_token}"
curl -sS "https://api.rora.carmel.so/api/partner/linq/claim/$TOKEN" | jq .

Verify

  • valid: true
  • Response includes agent_id, signup_url, dashboard_url, redeem_url
  • claim_url matches agentstatus.dev/linq/claim?token=…
10

Claim landing page (Tier 3 gate)

Open reliability.claim_url from step 3 in a browser.

open "https://agentstatus.dev/linq/claim?token={claim_token}"

Verify

  • Page loads without login
  • Shows agent name, locator, and current reliability label
  • Continue / signup links present
11

Linq — claim link + optional owner_email (Tier 3 gate)

Wire claim_url for power users. Pass owner_email on webhook when known.

{# Use reliability.claim_url from status poll #}
<a href="{{ reliability.claim_url }}" target="_blank" rel="noopener noreferrer">
  Manage alerts &amp; metrics
</a>

Verify

  • “Manage alerts & metrics” links to reliability.claim_url
  • Tier 1 toggle still does not require Agent Status signup

Tier 1 delivery checklist

Agent Status engineering

4 / 5 done
  • DonePartner API live on api.rora.carmel.so
  • DonePartner credentials issued to Linq (webhook secret + status token)
  • DoneLinq adapter + portfolio bootstrap defaults
  • DoneTier 2 report + badge and Tier 3 claim flow shipped (API + pages)
  • TodoPilot: 5–10 Linq locators onboarded via Tier 1 webhook

Linq delivers

1 / 4 done
  • TodoTier 1 toggle → webhook wired
  • Todoreliability field rendered in partner UI
  • TodoList of pilot locators with sandbox lines
  • DoneDemo locator validated (sandbox-pilot-demo)

Success criteria (after E2E passes)

CheckTarget
Tier 1 E2E (steps 1–5)Pass on sandbox-pilot-demo locator
Tier 2 E2E (steps 6–8)Public report + Linq View full report (+ optional badge)
Tier 3 E2E (steps 9–11)Claim flow + Linq Manage alerts link
Linq Tier 1 UIreliability field renders from status poll
Pilot agents onboarded≥ 5 locators via webhook
Observation window≥ 7 days
Probe runs per agent≥ 15 (medium confidence)

Rollback

  • Pause via webhook: event: monitoring.disabled
  • Or pause agent: PATCH /api/rora/agents/{id} status: paused

Partner API lives on https://api.rora.carmel.so. Webhook URL: POST https://api.rora.carmel.so/api/partner/linq/webhooks/monitoring. Secrets shared out-of-band with Linq engineering.