Skip to content
You are reading the HappyView v2 docs, which are no longer updated. Read the v3 docs.

Backfill

Create and monitor historical backfill jobs. See the Backfill guide for background.

const TOKEN = "hv_..."; // your API key
const headers = { Authorization: `Bearer ${TOKEN}` };
POST /admin/backfill
interface BackfillJob {
id: string;
status: string;
}
const response = await fetch("http://127.0.0.1:3000/admin/backfill", {
method: "POST",
headers: {
...headers,
"Content-Type": "application/json",
},
body: JSON.stringify({
collection: "xyz.statusphere.status",
}),
});
const data: BackfillJob = await response.json();
FieldTypeRequiredDescription
collectionstringnoLimit to a single collection (backfills all if omitted)
didsstring[]noAccounts to backfill, as DIDs or handles (discovers all via relay if omitted)
didstringnoA single account; kept for compatibility and added to dids

Every entry in dids must resolve, or the request fails with 400 listing each entry that did not and no job is created. Duplicates are ignored. A request can name at most 500 accounts.

Response: 201 Created

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running"
}
POST /admin/backfill/{id}/cancel

Requests cancellation of a running backfill job. The job status transitions to cancelling immediately; the background worker will stop at its next checkpoint and set the final status to cancelled. See the Backfill guide for details on the two-phase process.

const response = await fetch(
`http://127.0.0.1:3000/admin/backfill/${jobId}/cancel`,
{ method: "POST", headers },
);
const data = await response.json();

Response: 200 OK

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "cancelling"
}

Returns 400 if the job is not currently running, or 404 if the job ID is not found.

POST /admin/backfill/{id}/pause

Requests a running backfill job to pause. The job status transitions to pausing immediately; the background worker will stop at its next checkpoint and set the status to paused. Paused jobs retain all progress and can be resumed later.

Terminal window
curl -X POST "http://127.0.0.1:3000/admin/backfill/$JOB_ID/pause" -H "$AUTH"

Response: 200 OK

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pausing"
}

Returns 400 if the job is not currently running, or 404 if the job ID is not found.

POST /admin/backfill/{id}/resume

Resume a paused backfill job. The job status transitions back to running and processing continues from where it left off.

Terminal window
curl -X POST "http://127.0.0.1:3000/admin/backfill/$JOB_ID/resume" -H "$AUTH"

Response: 200 OK

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running"
}

Returns 400 if the job is not currently paused, or 404 if the job ID is not found.

GET /admin/backfill/status
interface BackfillJob {
id: string;
collection: string | null;
did: string | null;
scope: "network" | "dids";
status: string;
stage: string;
total_repos: number | null;
resolved_repos: number | null;
processed_repos: number | null;
total_records: number | null;
error: string | null;
started_at: string | null;
completed_at: string | null;
created_at: string;
}
const response = await fetch("http://127.0.0.1:3000/admin/backfill/status", {
headers,
});
const data: BackfillJob[] = await response.json();

Response: 200 OK

[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"collection": "xyz.statusphere.status",
"did": null,
"scope": "network",
"status": "completed",
"stage": "completed",
"total_repos": 42,
"resolved_repos": 42,
"processed_repos": 42,
"total_records": 1000,
"error": null,
"started_at": "2025-01-01T00:01:00Z",
"completed_at": "2025-01-01T00:05:00Z",
"created_at": "2025-01-01T00:00:00Z"
}
]

The status field tracks the overall job state (running, pausing, paused, cancelling, cancelled, completed, failed). The stage field tracks the current processing phase (pending, discovering_repos, resolving_and_fetching, completed, failed, cancelled). The resolved_repos counter tracks PDS resolution progress during the pipelined phase, while processed_repos tracks record fetching progress.

scope is network when repos are discovered through the relay and dids when the job targets specific accounts. did is set only when a job targets exactly one account.

GET /admin/backfill/{id}/repos

Paginated list of per-DID tracking rows for a backfill job. Requires BackfillRead.

ParamTypeRequiredDescription
phasestringnoFilter: discovered (all), resolved (PDS known), fetched (completed)
cursorstringnoKeyset cursor (DID) for pagination
limitnumbernoMax results per page (default 50, max 100)
Terminal window
curl "http://127.0.0.1:3000/admin/backfill/$JOB_ID/repos?phase=fetched&limit=10" -H "$AUTH"

Response: 200 OK

{
"repos": [
{ "did": "did:plc:abc", "pds_endpoint": "https://pds.example.com", "status": "completed", "records_fetched": 42 }
],
"cursor": "did:plc:def"
}

cursor is null when there are no more results.

GET /admin/backfill/{id}/pds-summary

Aggregated PDS breakdown for a backfill job. Requires BackfillRead. No pagination — returns all PDS endpoints in one response, sorted by repo count descending.

Terminal window
curl "http://127.0.0.1:3000/admin/backfill/$JOB_ID/pds-summary" -H "$AUTH"

Response: 200 OK

{
"pds_endpoints": [
{ "pds_endpoint": "https://morel.us-east.host.bsky.network", "total_repos": 1200, "completed_repos": 800, "total_records": 5000 }
]
}
GET /admin/backfill/{id}/events

Server-Sent Events stream of real-time backfill progress. Requires BackfillRead. The connection stays open until the job completes or the client disconnects. A keepalive comment is sent periodically to prevent timeouts.

Events are sent with event: event and a JSON data payload. Each event has a type field:

Event typeDescription
repo_discoveredA new DID was found during the discovery phase
repo_resolvedA DID’s PDS endpoint was resolved
repo_fetchedRecord fetching completed for a DID
job_countersUpdated progress counters
job_stage_changedThe job moved to a new processing stage
job_completedThe job finished (completed, failed, or cancelled)
DELETE /admin/backfill/{id}/details

Delete all per-repo tracking rows for a single backfill job. Requires BackfillCreate.

Terminal window
curl -X DELETE "http://127.0.0.1:3000/admin/backfill/$JOB_ID/details" -H "$AUTH"

Response: 204 No Content

DELETE /admin/backfill/details

Delete per-repo tracking rows for all completed, cancelled, and failed backfill jobs. Requires BackfillCreate.

Terminal window
curl -X DELETE "http://127.0.0.1:3000/admin/backfill/details" -H "$AUTH"

Response: 204 No Content