Accounts

Connected platform accounts (facebook, x, reddit).

This is not the live API. This page documents an earlier, in-browser mock API (routes like /accounts, /messaging and /brand), kept for reference. The real, read-only API that runs today is described in The API.

Accounts — connected platform identities

Accounts are the ConnectionRecord[] the dashboard's Accounts table shows — each has id, platform (facebook/x/reddit), label, and connectedAt. They are the FKs every group join and listing creation scopes through. The mock seeds from MOCK_CONNECTIONS and persists mutations.

Four routes: list all, create by platform (validates allowlist), patch by id (id is immutable, other fields merge), and delete. Code: apps/web/src/lib/connections/server.ts.

GET /accounts — List accounts

Returns all connected platform accounts (ConnectionRecord[] with id, platform facebook/x/reddit, label, and connectedAt). This is the roster the dashboard's Accounts table and every group/listings scope picker reads. No parameters. Code: apps/web/src/lib/connections/server.ts:15

POST /accounts — Create account

Creates a new ConnectionRecord for platform facebook/x/reddit. Generates a stable id (account-<timestamp>-<rand>), sets label from the platform name, and connectedAt: null until the extension verifies the session. Returns 201 with the created record and the full list. Rejects unknown platforms with 400 platform must be facebook, x, or reddit. Code: apps/web/src/lib/connections/server.ts:16

PATCH /accounts/{accountId} — Update account

Patches the ConnectionRecord for :accountId — merges the JSON body over the stored record but keeps id immutable (id from the path always wins). Used by the dashboard to update labels, or stamp connectedAt after extension verification. Returns 404 Account not found if the id is unknown. Code: apps/web/src/lib/connections/server.ts:32

DELETE /accounts/{accountId} — Delete account

Hard-deletes the account row by accountId. The row leaves the store entirely and is removed from any community join relations on next read. Returns 404 Account not found for unknown ids. Code: apps/web/src/lib/connections/server.ts:43

POST /accounts/{accountId}/resolve — Resolve account challenge

Clears a human-resolved challenge on :accountId: the visitor passed the checkpoint / interstitial / captcha in the session view, so lastIssue, rawSignal and retryAfter go away, lastCheckedAt is stamped, and a missing connectedAt is backfilled. Only accounts whose lastIssue is in the resolvable set (checkpointed, challenge_interstitial, captcha_html) qualify — anything else (including a healthy account) returns 409 No resolvable challenge on this account. Unknown ids return 404 Account not found. Dashboard-only: human verification happens in the resolver view, so API keys never call this. Code: apps/web/src/lib/connections/server.ts:50

List accounts

Returns all connected platform accounts (ConnectionRecord[] with id, platform facebook/x/reddit, label, and connectedAt). This is the roster the dashboard's Accounts table and every group/listings scope picker reads. No parameters. Code: apps/web/src/lib/connections/server.ts:15

GET/accounts

Response Body

Account list.

TypeScript Definitions

Use the response body type in TypeScript.

accountsRequiredarray<object>
curl -X GET "http://localhost:5174/accounts"
fetch("http://localhost:5174/accounts")
package mainimport (  "fmt"  "net/http"  "io/ioutil")func main() {  url := "http://localhost:5174/accounts"  req, _ := http.NewRequest("GET", url, nil)    res, _ := http.DefaultClient.Do(req)  defer res.Body.Close()  body, _ := ioutil.ReadAll(res.Body)  fmt.Println(res)  fmt.Println(string(body))}
import requestsurl = "http://localhost:5174/accounts"response = requests.request("GET", url)print(response.text)
{
  "accounts": [
    {
      "property1": null,
      "property2": null
    }
  ]
}

Create account

Creates a new ConnectionRecord for platform facebook/x/reddit. Generates a stable id (account-<timestamp>-<rand>), sets label from the platform name, and connectedAt: null until the extension verifies the session. Returns 201 with the created record and the full list. Rejects unknown platforms with 400 platform must be facebook, x, or reddit. Code: apps/web/src/lib/connections/server.ts:16

POST/accounts

Request Body

application/jsonRequired
platformRequiredstring

Platform to connect.

Value in: "facebook" | "x" | "reddit"

Response Body

Created.

TypeScript Definitions

Use the response body type in TypeScript.

accountRequiredobject

ConnectionRecord — connected platform account.

accountsRequiredarray<object>

Failure envelope returned with 4xx statuses.

TypeScript Definitions

Use the response body type in TypeScript.

errorRequiredstring

Human-readable failure reason, e.g. "A key needs a name".

curl -X POST "http://localhost:5174/accounts" \  -H "Content-Type: application/json" \  -d '{    "platform": "facebook"  }'
const body = JSON.stringify({  "platform": "facebook"})fetch("http://localhost:5174/accounts", {  body})
package mainimport (  "fmt"  "net/http"  "io/ioutil"  "strings")func main() {  url := "http://localhost:5174/accounts"  body := strings.NewReader(`{    "platform": "facebook"  }`)  req, _ := http.NewRequest("POST", url, body)  req.Header.Add("Content-Type", "application/json")  res, _ := http.DefaultClient.Do(req)  defer res.Body.Close()  body, _ := ioutil.ReadAll(res.Body)  fmt.Println(res)  fmt.Println(string(body))}
import requestsurl = "http://localhost:5174/accounts"body = {  "platform": "facebook"}response = requests.request("POST", url, json = body, headers = {  "Content-Type": "application/json"})print(response.text)
{
  "account": {
    "property1": null,
    "property2": null
  },
  "accounts": [
    {
      "property1": null,
      "property2": null
    }
  ]
}
{
  "error": "string"
}

Update account

Patches the ConnectionRecord for :accountId — merges the JSON body over the stored record but keeps id immutable (id from the path always wins). Used by the dashboard to update labels, or stamp connectedAt after extension verification. Returns 404 Account not found if the id is unknown. Code: apps/web/src/lib/connections/server.ts:32

PATCH/accounts/{accountId}

Request Body

application/jsonRequired

Path Parameters

accountIdRequiredstring

Account id.

Response Body

Updated list.

TypeScript Definitions

Use the response body type in TypeScript.

accountsRequiredarray<object>

Failure envelope returned with 4xx statuses.

TypeScript Definitions

Use the response body type in TypeScript.

errorRequiredstring

Human-readable failure reason, e.g. "A key needs a name".

curl -X PATCH "http://localhost:5174/accounts/string" \  -H "Content-Type: application/json" \  -d '{}'
const body = JSON.stringify({})fetch("http://localhost:5174/accounts/string", {  body})
package mainimport (  "fmt"  "net/http"  "io/ioutil"  "strings")func main() {  url := "http://localhost:5174/accounts/string"  body := strings.NewReader(`{}`)  req, _ := http.NewRequest("PATCH", url, body)  req.Header.Add("Content-Type", "application/json")  res, _ := http.DefaultClient.Do(req)  defer res.Body.Close()  body, _ := ioutil.ReadAll(res.Body)  fmt.Println(res)  fmt.Println(string(body))}
import requestsurl = "http://localhost:5174/accounts/string"body = {}response = requests.request("PATCH", url, json = body, headers = {  "Content-Type": "application/json"})print(response.text)
{
  "accounts": [
    {
      "property1": null,
      "property2": null
    }
  ]
}
{
  "error": "string"
}

Delete account

Hard-deletes the account row by accountId. The row leaves the store entirely and is removed from any community join relations on next read. Returns 404 Account not found for unknown ids. Code: apps/web/src/lib/connections/server.ts:43

DELETE/accounts/{accountId}

Path Parameters

accountIdRequiredstring

Account id.

Response Body

Remaining list.

TypeScript Definitions

Use the response body type in TypeScript.

accountsRequiredarray<object>

Failure envelope returned with 4xx statuses.

TypeScript Definitions

Use the response body type in TypeScript.

errorRequiredstring

Human-readable failure reason, e.g. "A key needs a name".

curl -X DELETE "http://localhost:5174/accounts/string"
fetch("http://localhost:5174/accounts/string")
package mainimport (  "fmt"  "net/http"  "io/ioutil")func main() {  url := "http://localhost:5174/accounts/string"  req, _ := http.NewRequest("DELETE", url, nil)    res, _ := http.DefaultClient.Do(req)  defer res.Body.Close()  body, _ := ioutil.ReadAll(res.Body)  fmt.Println(res)  fmt.Println(string(body))}
import requestsurl = "http://localhost:5174/accounts/string"response = requests.request("DELETE", url)print(response.text)
{
  "accounts": [
    {
      "property1": null,
      "property2": null
    }
  ]
}
{
  "error": "string"
}

Resolve account challenge

Clears a human-resolved challenge on :accountId: the visitor passed the checkpoint / interstitial / captcha in the session view, so lastIssue, rawSignal and retryAfter go away, lastCheckedAt is stamped, and a missing connectedAt is backfilled. Only accounts whose lastIssue is in the resolvable set (checkpointed, challenge_interstitial, captcha_html) qualify — anything else (including a healthy account) returns 409 No resolvable challenge on this account. Unknown ids return 404 Account not found. Dashboard-only: human verification happens in the resolver view, so API keys never call this. Code: apps/web/src/lib/connections/server.ts:50

POST/accounts/{accountId}/resolve

Path Parameters

accountIdRequiredstring

Account id.

Response Body

Resolved account and list.

TypeScript Definitions

Use the response body type in TypeScript.

accountRequiredobject

ConnectionRecord — connected platform account.

accountsRequiredarray<object>

Failure envelope returned with 4xx statuses.

TypeScript Definitions

Use the response body type in TypeScript.

errorRequiredstring

Human-readable failure reason, e.g. "A key needs a name".

Failure envelope returned with 4xx statuses.

TypeScript Definitions

Use the response body type in TypeScript.

errorRequiredstring

Human-readable failure reason, e.g. "A key needs a name".

curl -X POST "http://localhost:5174/accounts/string/resolve"
fetch("http://localhost:5174/accounts/string/resolve")
package mainimport (  "fmt"  "net/http"  "io/ioutil")func main() {  url := "http://localhost:5174/accounts/string/resolve"  req, _ := http.NewRequest("POST", url, nil)    res, _ := http.DefaultClient.Do(req)  defer res.Body.Close()  body, _ := ioutil.ReadAll(res.Body)  fmt.Println(res)  fmt.Println(string(body))}
import requestsurl = "http://localhost:5174/accounts/string/resolve"response = requests.request("POST", url)print(response.text)
{
  "account": {
    "property1": null,
    "property2": null
  },
  "accounts": [
    {
      "property1": null,
      "property2": null
    }
  ]
}
{
  "error": "string"
}
{
  "error": "string"
}