hydrant docs
hydrant docsfor hydrant 0.1.0
hydrant 0.1.0

all /repos endpoints that return lists respond with NDJSON by default. send Accept: application/json or Content-Type: application/json to get a JSON array instead.

PUT /repos, DELETE /repos and POST /repos/resync hand each DID to the indexer shard that owns it, which commits it on its own, so a request that fails partway has already applied some of its DIDs. sending it again is safe, since each DID's change is idempotent.

GET /repos

get a list of repositories and their sync status. supports pagination and filtering:

param description
limit max results (default 100, max 1000)
cursor did key for paginating
queued true to list only the repositories hydrant still has work queued for, a pending backfill or a resync entry (see below). same order and cursor as the full list, so a repository that moves between the two queues while you page keeps its place. the cost of a page follows how much is queued, not how many repositories hydrant knows. indexer mode only

GET /repos/{did}

get the sync status and metadata of a specific repository. also returns the handle, PDS URL and the atproto signing key (these won't be available before the repo has been backfilled at least once).

both endpoints say whether hydrant still has work queued for the repository: pending is true while a backfill of it is queued or running, and a resync object is there while it sits in the resync queue. a failed backfill waiting for its retry shows only resync, and it moves back to pending once the retry is due:

state fields meaning
error kind, retry_count, next_retry, host_failures the last backfill failed and is retried at next_retry. retry_count is how many backfills failed in a row, across retries, until one succeeds, and the wait doubles with it from about 2 minutes up to an hour (a skip because the PDS is throttled waits a minute and doesn't count). kind is ratelimited (the PDS asked to slow down, or hydrant skipped it because its PDS is throttled), transport (the PDS couldn't be reached) or generic (anything else). host_failures is how many transport failures in a row the repository's PDS has had since hydrant started, so a ratelimited repo on a PDS that keeps failing is waiting on a dead host rather than a rate limit
gone status the account is inactive (deactivated, takendown, ...) and gets backfilled again once it comes back

while a repository is pending or has a resync entry, don't read its records as a snapshot: a backfill writes them in steps, and one that fails partway leaves the steps it got through, so they can be a mix of the old repo and the new one until both are gone. getRepo answers RepoNotFound while it's pending, and while a failed backfill waits for its retry with records that don't match the repo's root.

PUT /repos

explicitly track repositories. accepts an NDJSON body of {"did": "..."} (or JSON array of the same). only affects repositories that are not known or are untracked. returns a list of the DIDs that were queued for backfill. a repository that's being erased, or whose deleted account is being wiped, is left out of the list: try it again once that's done.

DELETE /repos

untrack repositories. accepts an NDJSON body of {"did": "..."} (or JSON array of the same). only affects repositories that are currently tracked. returns a list of the DIDs that were untracked. a repository whose backfill is writing its records right now is left tracked and missing from the list, since stopping there would leave it half written: try it again once the backfill is done. a restart partway through keeps it counting as running until the backfill runs again. one hole remains: a backfill that fails partway through its records stops counting as running before it's queued for a retry, so an untrack in between leaves its repo half written and untracked, which tracking it again repairs.

DELETE /repos/{did}

untrack a single repository. returns a list containing the untracked DID, or an empty list while its backfill is writing its records, as above. does not erase stored bodies from disk (use /redactions for operator data erasure).

POST /redactions/{target}

operator data erasure. the target parameter accepts a DID (did:plc:... or at://did:plc:...) to erase a whole repository, or an AT-URI (at://did/.../collection/rkey or did/.../collection/rkey) to redact a single record.

a repository is erased whole: its records (cids included), history, buffered commits, backlinks, counts and the repo's own state are all deleted and it is untracked, so hydrant keeps nothing about it beyond stream events that point at bodies it no longer has. tracking it again later backfills it from scratch and emits every record as a create. the repository's indexer shard does the erasing a step at a time, between its live events, and the request answers once the last step is in. its live events are dropped meanwhile, and a restart partway through finishes the erase on its own.

a record keeps its cid and a marker in place of its body, since the repository is still indexed: the marker stops that exact version from being stored again, while a new version of the record is indexed as usual.

query param values description
target head, history, all which body copies of a record to delete (default all). rejected for a repository
exclude true, false whether to also add the DID to /filter excludes, keeping it from being indexed again (default false)

returns a JSON DeleteBodiesReport with how many heads, history entries, event bodies and buffered commits went, and the bytes of record content among them. rejected in ephemeral and links-only modes.

POST /repos/resync

force a new backfill for one or more repositories. accepts an NDJSON body of {"did": "..."} (or JSON array of the same). only affects repositories hydrant already knows about. returns a list of the DIDs that were queued, which leaves out one that's being erased or wiped, as for PUT /repos.