diff --git a/.agents/skills/hypercerts-api/SKILL.md b/.agents/skills/hypercerts-api/SKILL.md new file mode 100644 index 0000000..393a284 --- /dev/null +++ b/.agents/skills/hypercerts-api/SKILL.md @@ -0,0 +1,26 @@ +--- +name: hypercerts-api +description: Use whenever a user needs to call Hypercerts' public, read-only XRPC API directly; select an endpoint from the bundled contract, construct GET requests, paginate, and interpret indexed results from production or staging. +--- +Production: https://api.hypercerts.dev +Staging: https://api.staging.hypercerts.dev + +# Consuming the Hypercerts API + +This skill covers only the public, read-only HappyView XRPC query API. Every query is `GET /xrpc/` on the selected base URL. Requests need no authentication: do not add OAuth, login, bearer tokens, or API keys. This API does not provide writes. + +## Route by task + +- Choosing an endpoint or filter for a user task: [endpoint-map.md](references/endpoint-map.md). +- Planning a multi-call integration flow: [recipes.md](references/recipes.md). +- Building URLs, encoding arrays and filters, or continuing pages: [request-patterns.md](references/request-patterns.md). +- Distinguishing identities and versions, or handling stale, missing, nullable, or failed data: [reliability.md](references/reliability.md). + +Read the relevant reference, then inspect the exact operation in the [bundled OpenAPI contract](references/openapi.json) before constructing a request. Do not assume parameter names, array semantics, defaults, limits, cursor behavior, nullability, or errors are shared across endpoints. Use that operation's own parameters, schemas, descriptions, and declared errors. + +## Bundled API contract + +- [`references/openapi.json`](references/openapi.json) is a self-contained snapshot of all 55 query operations, including parameters, response schemas, declared XRPC errors, and their referenced schema definitions. The included contract makes the skill self-contained when installed separately. +- To inspect an exact contract, find `/xrpc/` in the snapshot, read its operation, and follow any `#/components/schemas/...` references by schema name. Each operation and schema is stored on its own line for focused lookup. +- The snapshot describes declared behavior, not endpoint availability or data freshness on a particular host. Its OpenAPI `info.version` is not the deployed server's version. +- Use the API directly when a task needs live indexed results. Do not send extra diagnostic probes just to validate deployment; a deployment-specific availability check requires explicit approval for the target. diff --git a/.agents/skills/hypercerts-api/references/endpoint-map.md b/.agents/skills/hypercerts-api/references/endpoint-map.md new file mode 100644 index 0000000..3572d22 --- /dev/null +++ b/.agents/skills/hypercerts-api/references/endpoint-map.md @@ -0,0 +1,122 @@ +# Endpoint map: choose by consumer task + +This task index lists the 55 public query NSIDs in the bundled [OpenAPI contract](openapi.json). It helps choose an operation but does not replace its exact contract: inspect that operation and its referenced schemas for required parameters, types, defaults, limits, filter semantics, response fields, and declared errors. The static snapshot describes the contract, not availability or freshness on a selected deployment. + +## Fast selection rules + +- **One known record or relationship:** choose its `get...` query and supply the exact documented identifier. Profile lookup is a special case: `getProfile` accepts a DID or handle; most record getters take an AT-URI. +- **Known actor DIDs in a batch:** prefer `getProfiles` or `getOrganizations`; batch results may have nullable per-actor values. Their batch inputs are DIDs, not handles. +- **Browse or filter without free text:** choose `list...` in the relevant domain. +- **Text discovery:** use `search...` only where listed below. A search query is not interchangeable with a list filter, and search semantics vary by endpoint. +- **Relationship checks:** use `get...Follow` for a single pair; list queries answer who follows whom or which entities an actor follows. + +Inspect the exact operation in the bundled OpenAPI contract before constructing a request: names such as `authors`, `actors`, `uri`, and `collection` have endpoint-specific meanings. Do not infer that a filter, search operation, output array name, or error exists just because a related endpoint has one. + +## People and organization context (8) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Load one Certified profile | `app.certified.actor.getProfile` | `actor` is one DID or handle. Handle resolution is part of this operation. | +| Load profiles for known actors | `app.certified.actor.getProfiles` | `actors` is a repeated array of DIDs; each result corresponds to an input occurrence and its profile may be null. | +| Browse indexed profiles | `app.certified.actor.listProfiles` | Use for paged discovery, not free-text search. | +| Find profiles by text | `app.certified.actor.searchProfiles` | `search` is required; optionally constrain by actor DIDs. Check this endpoint's text/filter rules. | +| Load one actor's organization sidecar | `app.certified.actor.getOrganization` | `actor` is a DID. If no indexed sidecar exists, this single lookup declares `RecordNotFound`; unlike `getOrganizations`, it does not return a nullable organization per actor. | +| Load organization context for known actors | `app.certified.actor.getOrganizations` | `actors` is a repeated DID array; results preserve request order and an absent organization is null per result. | +| Browse/filter organizations | `app.certified.actor.listOrganizations` | Use for organization-type/visibility filters and pagination. | +| Find organizations by text | `app.certified.actor.searchOrganizations` | Searches associated profile text, with optional organization filters. | + +Use `getProfiles`/`getOrganizations` for known DID sets; use `list` or `search` for discovery. A missing optional profile inside an organization view is not the same as a missing organization record. + +## Activities, contributors, contributions, and rights (9) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Load one activity | `org.hypercerts.claim.getActivity` | Exact activity AT-URI in `uri`; hydrated activity view. | +| Filter/browse activities | `org.hypercerts.claim.listActivities` | Use structured filters such as authors, contributors, involved actors, or exact activity URIs; no text query is required. | +| Search activities by text | `org.hypercerts.claim.searchActivities` | `search` is required; current contract describes a case-insensitive literal substring of title or short description. | +| Load one contribution | `org.hypercerts.claim.getContribution` | Exact record AT-URI in `uri`. | +| List contributions | `org.hypercerts.claim.listContributions` | Browse/filter by publisher DID. | +| Load one contributor-information record | `org.hypercerts.claim.getContributorInformation` | Exact record AT-URI in `uri`. | +| List contributor-information records | `org.hypercerts.claim.listContributorInformation` | Browse with an optional publisher-DID filter. | +| Load one rights record | `org.hypercerts.claim.getRights` | Exact DID-authority record AT-URI in `uri`. | +| List rights records | `org.hypercerts.claim.listRights` | Browse with an optional publisher-DID filter. | + +For activities, distinguish repository-owner `authors` from `contributors`; `involvedActors` has its own documented meaning. Check array combination and search behavior in the exact operation. + +## Collections and their contents (4) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Load one collection | `org.hypercerts.collection.getCollection` | Exact collection AT-URI in `uri`; hydrates selected related projections. | +| Find collections by filters | `org.hypercerts.collection.listCollections` | Use filters such as author, collection URI, item URI, or tag URI. Some URI filters intentionally ignore CID; inspect the contract. | +| Find collections by text | `org.hypercerts.collection.searchCollections` | `search` is required; current contract searches title/short description. Other filters still apply. | +| Resolve embedded collection items | `org.hypercerts.collection.listCollectionItems` | Pass the collection AT-URI. Resolves each embedded strong reference by exact URI+CID, one level deep; see [the collection recipe](recipes.md#load-exact-collection-item-versions). | + +Choose `listCollectionItems` when the caller needs the referenced item versions, not just collections matching an `itemUris` discovery filter. + +## Badges and recipient responses (7) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Load one badge definition | `app.certified.badge.getBadgeDefinition` | Exact definition AT-URI in `uri`. | +| Browse/filter badge definitions | `app.certified.badge.listBadgeDefinitions` | Use publisher/type filters and pagination. | +| Search badge definitions | `app.certified.badge.searchBadgeDefinitions` | `search` is required; use for text discovery, not status checking. | +| Load one award and its response status | `app.certified.badge.getBadgeAward` | Exact award AT-URI in `uri`; includes `responseStatus` (`accepted`, `rejected`, or `unanswered`) and nullable recipient response. | +| Browse/filter awards | `app.certified.badge.listBadgeAwards` | Use when the award URI is not known or multiple awards are needed; the result includes response status. | +| Load one raw response record | `app.certified.badge.getBadgeResponse` | Exact response AT-URI in `uri`. | +| List raw responses for an award | `app.certified.badge.listBadgeResponses` | Optional `badgeAward` filter; use to inspect response records, not as a substitute for the award's derived status. | + +An `unanswered` award is a successful indexed award result, not a not-found response. See [the badge recipe](recipes.md#read-badge-award-response-status). + +## Follow relationships (7) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Check one actor-to-actor follow | `app.certified.graph.getFollow` | Supply actor and subject DIDs; the representative `follow` may be null when none is indexed. | +| List an actor's followers | `app.certified.graph.listActorFollowers` | `actor` is the followed actor DID. | +| List actors an actor follows | `app.certified.graph.listActorFollowing` | `actor` is the follower DID. | +| Check one actor-to-entity follow | `app.certified.graph.getEntityFollow` | Supply actor DID and entity AT-URI; check its nullable/error contract. | +| List actors following an entity | `app.certified.graph.listEntityFollowers` | `entity` is an entity AT-URI. | +| List entities an actor follows | `app.certified.graph.listEntityFollowing` | `actor` is an actor DID; targets are hydrated from indexed records. | +| Browse recent raw follow records | `app.certified.graph.listRecentFollows` | Beta feed across publishers; `before` and pagination have distinct feed semantics. Not a per-actor relationship check. | + +Do not confuse actor follows with entity follows; their identifiers and list outputs differ. Recent raw follows preserve duplicates and are not a snapshot; consult that endpoint's description before using cursors. + +## Context and supporting records (8) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Load one acknowledgement | `org.hypercerts.context.getAcknowledgement` | Exact record AT-URI in `uri`. | +| List acknowledgements | `org.hypercerts.context.listAcknowledgements` | Filter by publisher or subject as documented. | +| Load one attachment | `org.hypercerts.context.getAttachment` | Exact record AT-URI in `uri`. | +| List attachments | `org.hypercerts.context.listAttachments` | Filter by publisher, record URI, subject, or content type. | +| Load one evaluation | `org.hypercerts.context.getEvaluation` | Exact record AT-URI in `uri`; includes publisher/evaluator projections. | +| List evaluations | `org.hypercerts.context.listEvaluations` | Filter by publisher, evaluator, or subject. | +| Load one measurement | `org.hypercerts.context.getMeasurement` | Exact record AT-URI in `uri`. | +| List measurements | `org.hypercerts.context.listMeasurements` | Filter by publisher or subject. | + +These records are context related to other Hypercert records, not alternate activity or collection search endpoints. Confirm whether each filter expects a DID or AT-URI. + +## Locations, features, and EVM links (6) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Load one location | `app.certified.location.getLocation` | Exact location AT-URI in `uri`. | +| List/filter locations | `app.certified.location.listLocations` | Filter by publisher, URI, or location type. | +| Load one feature | `org.hypercerts.entity.getFeature` | Exact feature AT-URI in `uri`; includes author hydration. | +| List/filter features | `org.hypercerts.entity.listFeatures` | Use publisher, organization-record, or type filters. | +| Load one EVM link | `app.certified.link.getEvmLink` | Exact EVM-link AT-URI in `uri`. | +| List EVM links | `app.certified.link.listEvmLinks` | Filter by actor DID or wallet address. | + +## Funding receipts and controlled tags (6) + +| User task | Query NSID | Practical choice | +|---|---|---| +| Load one funding receipt | `org.hypercerts.funding.getReceipt` | Exact receipt AT-URI in `uri`. | +| Find/list funding receipts | `org.hypercerts.funding.listReceipts` | Combine the documented publisher, URI, from/to, related-record, or transaction filters. | +| Load one vocabulary tag | `org.hypercerts.vocab.getVocabTag` | Exact tag AT-URI in `uri`. | +| List vocabulary tags | `org.hypercerts.vocab.listVocabTags` | Browse by publisher DID. | +| Load one work-scope tag | `org.hypercerts.workscope.getWorkscopeTag` | Exact tag AT-URI in `uri`. | +| List work-scope tags | `org.hypercerts.workscope.listWorkscopeTags` | Browse by publisher DID. | + +Use the specific tag family required by the calling record. Similar-looking tags are separate record families and are not interchangeable. diff --git a/.agents/skills/hypercerts-api/references/openapi.json b/.agents/skills/hypercerts-api/references/openapi.json new file mode 100644 index 0000000..aadcd5a --- /dev/null +++ b/.agents/skills/hypercerts-api/references/openapi.json @@ -0,0 +1,195 @@ +{ + "openapi": "3.1.0", + "info": {"title":"Hypercerts API","version":"contract-snapshot","description":"Public, read-only Hypercerts XRPC query endpoints. This static contract snapshot describes declared behavior, not availability on a particular deployment."}, + "servers": [{"url":"https://api.hypercerts.dev","description":"Production API"},{"url":"https://api.staging.hypercerts.dev","description":"Staging API"}], + "tags": [{"name":"app.certified.actor"},{"name":"app.certified.badge"},{"name":"app.certified.graph"},{"name":"app.certified.link"},{"name":"app.certified.location"},{"name":"org.hypercerts.claim"},{"name":"org.hypercerts.collection"},{"name":"org.hypercerts.context"},{"name":"org.hypercerts.entity"},{"name":"org.hypercerts.funding"},{"name":"org.hypercerts.vocab"},{"name":"org.hypercerts.workscope"}], + "paths": { + "/xrpc/app.certified.actor.getOrganization": {"get":{"operationId":"app_certified_actor_getOrganization","tags":["app.certified.actor"],"description":"Gets an actor's indexed organization sidecar and associated profile by DID. Authentication is not required.","parameters":[{"name":"actor","in":"query","required":true,"description":"DID of the actor to look up.","schema":{"type":"string","format":"did"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.getOrganization.output"}}}}},"x-lexicon-id":"app.certified.actor.getOrganization","x-lexicon-errors":[{"name":"InvalidRequest","description":"The actor DID is invalid or an unsupported parameter was supplied."},{"name":"RecordNotFound","description":"No indexed organization sidecar exists for this DID."},{"name":"OrganizationQueryFailed","description":"The indexed organization sidecar or associated profile could not be queried."}]}}, + "/xrpc/app.certified.actor.getOrganizations": {"get":{"operationId":"app_certified_actor_getOrganizations","tags":["app.certified.actor"],"description":"Returns an indexed organization sidecar and associated profile for each supplied actor DID. Authentication is not required.","parameters":[{"name":"actors","in":"query","required":true,"description":"Actor DIDs to look up, supplied as repeated unbracketed query values.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.getOrganizations.output"}}}}},"x-lexicon-id":"app.certified.actor.getOrganizations","x-lexicon-errors":[{"name":"InvalidRequest","description":"An actor DID or query parameter is invalid."},{"name":"OrganizationQueryFailed","description":"The indexed organization sidecars or associated profiles could not be queried."}]}}, + "/xrpc/app.certified.actor.getProfile": {"get":{"operationId":"app_certified_actor_getProfile","tags":["app.certified.actor"],"description":"Gets an indexed Certified profile by DID or handle. Handles resolve through the configured resolver's com.atproto.identity.resolveHandle endpoint; no DID document is fetched for independent verification. Authentication is not required.","parameters":[{"name":"actor","in":"query","required":true,"description":"DID or handle of the profile actor.","schema":{"type":"string","format":"at-identifier"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.getProfile.output"}}}}},"x-lexicon-id":"app.certified.actor.getProfile","x-lexicon-errors":[{"name":"InvalidRequest","description":"The actor is not a valid DID or handle, or an unsupported parameter was supplied."},{"name":"HandleResolverConfigError","description":"HYPERCERTS_HANDLE_RESOLVER_URL is missing or invalid."},{"name":"HandleResolutionFailed","description":"The handle could not be resolved to a valid DID."},{"name":"RecordNotFound","description":"The actor was identified, but no indexed Certified profile exists."},{"name":"ProfileQueryFailed","description":"The indexed profile could not be queried."}]}}, + "/xrpc/app.certified.actor.getProfiles": {"get":{"operationId":"app_certified_actor_getProfiles","tags":["app.certified.actor"],"description":"Returns an indexed Certified profile for each supplied actor DID. Authentication is not required.","parameters":[{"name":"actors","in":"query","required":true,"description":"Actor DIDs to look up, supplied as repeated unbracketed query values.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.getProfiles.output"}}}}},"x-lexicon-id":"app.certified.actor.getProfiles","x-lexicon-errors":[{"name":"InvalidRequest","description":"An actor DID or query parameter is invalid."},{"name":"ProfileQueryFailed","description":"The indexed profiles could not be queried."}]}}, + "/xrpc/app.certified.actor.listOrganizations": {"get":{"operationId":"app_certified_actor_listOrganizations","tags":["app.certified.actor"],"description":"Lists actors with indexed organization sidecars matching the supplied filters. Filters combine with AND, and values within each array filter are ORed. Authentication is not required.","parameters":[{"name":"organizationTypes","in":"query","required":false,"description":"Exact organizationType values; OR within this filter.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":128}},"style":"form","explode":true},{"name":"visibility","in":"query","required":false,"description":"Exact visibility match; omission is unrestricted, but records with no visibility value do not match.","schema":{"type":"string"}},{"name":"sortDirection","in":"query","required":false,"description":"Sort by a valid zoned createdAt, otherwise indexedAt, falling back to row creation time; URI breaks ties. Default desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Page size; default 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep other parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.listOrganizations.output"}}}}},"x-lexicon-id":"app.certified.actor.listOrganizations","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter or scalar parameter is invalid or repeated, or an unsupported parameter was supplied."},{"name":"OrganizationQueryFailed","description":"The indexed organization sidecar or associated profile could not be queried."}]}}, + "/xrpc/app.certified.actor.listProfiles": {"get":{"operationId":"app_certified_actor_listProfiles","tags":["app.certified.actor"],"description":"Lists indexed Certified profiles with pagination. Authentication is not required.","parameters":[{"name":"sortDirection","in":"query","required":false,"description":"Sort by a valid zoned createdAt, otherwise indexedAt, falling back to row creation time; URI breaks ties. Default desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Page size; default 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep parameters unchanged between pages. Pages are not a snapshot.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.listProfiles.output"}}}}},"x-lexicon-id":"app.certified.actor.listProfiles","x-lexicon-errors":[{"name":"InvalidRequest","description":"A pagination parameter is invalid, repeated where scalar, or unsupported."},{"name":"ProfileQueryFailed","description":"The indexed profiles could not be queried."}]}}, + "/xrpc/app.certified.actor.searchOrganizations": {"get":{"operationId":"app_certified_actor_searchOrganizations","tags":["app.certified.actor"],"description":"Searches organizations by associated profile text and optional filters. Filters combine with AND, and values within each array filter are ORed. Authentication is not required.","parameters":[{"name":"search","in":"query","required":true,"description":"Trimmed text is matched literally and case-insensitively as a substring in either displayName or description. Blank text is unrestricted; nonblank text requires an associated profile.","schema":{"type":"string"}},{"name":"actors","in":"query","required":false,"description":"Actor DIDs to include; values are ORed and handles are not resolved.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"organizationTypes","in":"query","required":false,"description":"Exact organizationType values; OR within this filter.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":128}},"style":"form","explode":true},{"name":"visibility","in":"query","required":false,"description":"Exact visibility match; omission is unrestricted, but records with no visibility value do not match.","schema":{"type":"string"}},{"name":"sortDirection","in":"query","required":false,"description":"Sort by a valid zoned createdAt, otherwise indexedAt, falling back to row creation time; URI breaks ties. Default desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Page size; default 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep other parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.searchOrganizations.output"}}}}},"x-lexicon-id":"app.certified.actor.searchOrganizations","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter or scalar parameter is invalid or repeated, or an unsupported parameter was supplied."},{"name":"OrganizationQueryFailed","description":"The indexed organization sidecar or associated profile could not be queried."}]}}, + "/xrpc/app.certified.actor.searchProfiles": {"get":{"operationId":"app_certified_actor_searchProfiles","tags":["app.certified.actor"],"description":"Searches indexed Certified profiles by text, optionally restricted to actor DIDs. Filters combine with AND; values in the actor array are ORed. Authentication is not required.","parameters":[{"name":"search","in":"query","required":true,"description":"Trimmed text is matched literally and case-insensitively as a substring in displayName or description. Blank text is unrestricted.","schema":{"type":"string"}},{"name":"sortDirection","in":"query","required":false,"description":"Sort by a valid zoned createdAt, otherwise indexedAt, falling back to row creation time; URI breaks ties. Default desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"actors","in":"query","required":false,"description":"Actor DIDs to include; values are ORed and handles are not resolved.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"limit","in":"query","required":false,"description":"Page size; default 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep parameters unchanged between pages. Pages are not a snapshot.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.actor.searchProfiles.output"}}}}},"x-lexicon-id":"app.certified.actor.searchProfiles","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter or pagination parameter is invalid, repeated where scalar, or unsupported."},{"name":"ProfileQueryFailed","description":"The indexed profiles could not be queried."}]}}, + "/xrpc/app.certified.badge.getBadgeAward": {"get":{"operationId":"app_certified_badge_getBadgeAward","tags":["app.certified.badge"],"description":"Gets a badge award and its recipient response by AT-URI without authentication.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full AT-URI of the badge-award record.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.badge.getBadgeAward.output"}}}}},"x-lexicon-id":"app.certified.badge.getBadgeAward","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a badge-award AT-URI."},{"name":"RecordNotFound","description":"No indexed badge award exists at this AT-URI."},{"name":"BadgeAwardQueryFailed","description":"The indexed badge award could not be queried."}]}}, + "/xrpc/app.certified.badge.getBadgeDefinition": {"get":{"operationId":"app_certified_badge_getBadgeDefinition","tags":["app.certified.badge"],"description":"Returns an indexed badge definition and its publisher actor. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"AT-URI of a badge definition with a DID authority; lookup matches the URI, not a record CID.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.badge.getBadgeDefinition.output"}}}}},"x-lexicon-id":"app.certified.badge.getBadgeDefinition","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or does not identify a badge-definition AT-URI with a DID authority."},{"name":"RecordNotFound","description":"No indexed badge definition matches this AT-URI."}]}}, + "/xrpc/app.certified.badge.getBadgeResponse": {"get":{"operationId":"app_certified_badge_getBadgeResponse","tags":["app.certified.badge"],"description":"Gets one badge response by AT-URI without authentication.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full AT-URI of the badge-response record.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.badge.getBadgeResponse.output"}}}}},"x-lexicon-id":"app.certified.badge.getBadgeResponse","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a badge-response AT-URI."},{"name":"RecordNotFound","description":"No indexed badge response exists at this AT-URI."},{"name":"BadgeResponseQueryFailed","description":"The indexed badge response could not be queried."}]}}, + "/xrpc/app.certified.badge.listBadgeAwards": {"get":{"operationId":"app_certified_badge_listBadgeAwards","tags":["app.certified.badge"],"description":"Lists public badge awards with recipient response status and pagination without authentication.","parameters":[{"name":"authors","in":"query","required":false,"description":"DIDs of repositories that published the awards.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"badgeUris","in":"query","required":false,"description":"Badge-definition AT-URIs.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"badgeTypes","in":"query","required":false,"description":"Exact badgeType values from the referenced definition version.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":100}},"style":"form","explode":true},{"name":"subjects","in":"query","required":false,"description":"DIDs or full record AT-URIs with valid collection NSIDs.","schema":{"type":"array","maxItems":100,"items":{"type":"string"}},"style":"form","explode":true},{"name":"responses","in":"query","required":false,"description":"Computed recipient response statuses.","schema":{"type":"array","maxItems":100,"items":{"type":"string","enum":["accepted","rejected","unanswered"]}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction for (createdAt, uri).","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum awards returned.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.badge.listBadgeAwards.output"}}}}},"x-lexicon-id":"app.certified.badge.listBadgeAwards","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter or page parameter is invalid."},{"name":"BadgeAwardQueryFailed","description":"The indexed badge awards could not be queried."}]}}, + "/xrpc/app.certified.badge.listBadgeDefinitions": {"get":{"operationId":"app_certified_badge_listBadgeDefinitions","tags":["app.certified.badge"],"description":"Lists indexed badge definitions. Author and badgeType filters are combined with AND; values within each filter are matched with OR. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher DIDs to include.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"badgeTypes","in":"query","required":false,"description":"Exact badgeType strings to include.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":100}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Selects ascending or descending order by createdAt, then AT-URI.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of definitions to return in the page.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from the previous page, bound to sortDirection. Keep other query parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.badge.listBadgeDefinitions.output"}}}}},"x-lexicon-id":"app.certified.badge.listBadgeDefinitions","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter, query parameter, page bound, or cursor is invalid."}]}}, + "/xrpc/app.certified.badge.listBadgeResponses": {"get":{"operationId":"app_certified_badge_listBadgeResponses","tags":["app.certified.badge"],"description":"Lists raw public badge responses with optional award filtering and pagination without authentication.","parameters":[{"name":"badgeAward","in":"query","required":false,"description":"Badge-award AT-URI to match against response records.","schema":{"type":"string","format":"at-uri"}},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction for (createdAt, uri).","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum responses returned.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.badge.listBadgeResponses.output"}}}}},"x-lexicon-id":"app.certified.badge.listBadgeResponses","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter or page parameter is invalid."},{"name":"BadgeResponseQueryFailed","description":"The indexed badge responses could not be queried."}]}}, + "/xrpc/app.certified.badge.searchBadgeDefinitions": {"get":{"operationId":"app_certified_badge_searchBadgeDefinitions","tags":["app.certified.badge"],"description":"Searches badge definitions by title or description without authentication.","parameters":[{"name":"search","in":"query","required":true,"description":"Text matched against definition titles and descriptions.","schema":{"type":"string"}},{"name":"authors","in":"query","required":false,"description":"DIDs of repositories that published the definitions.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"badgeTypes","in":"query","required":false,"description":"Exact badgeType values.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":100}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction for (createdAt, uri).","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum definitions returned.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.badge.searchBadgeDefinitions.output"}}}}},"x-lexicon-id":"app.certified.badge.searchBadgeDefinitions","x-lexicon-errors":[{"name":"InvalidRequest","description":"A parameter is invalid, repeated where scalar, or unknown."},{"name":"BadgeDefinitionQueryFailed","description":"The indexed badge definitions could not be queried."}]}}, + "/xrpc/app.certified.graph.getEntityFollow": {"get":{"operationId":"app_certified_graph_getEntityFollow","tags":["app.certified.graph"],"description":"Returns the representative entity-follow record for an actor and entity AT-URI, or null if none is indexed. No authentication is required; lookup failures return errors rather than null.","parameters":[{"name":"actor","in":"query","required":true,"description":"DID that published the entity-follow record.","schema":{"type":"string","format":"did"}},{"name":"entity","in":"query","required":true,"description":"Full AT-URI of the followed record using a DID authority; any target collection is accepted, and matching is by URI, not CID.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.graph.getEntityFollow.output"}}}}},"x-lexicon-id":"app.certified.graph.getEntityFollow","x-lexicon-errors":[{"name":"InvalidRequest","description":"The actor DID, entity AT-URI, or another query parameter is invalid."}]}}, + "/xrpc/app.certified.graph.getFollow": {"get":{"operationId":"app_certified_graph_getFollow","tags":["app.certified.graph"],"description":"Returns the representative follow record for an actor-to-actor relationship, or null if none is indexed. No authentication is required.","parameters":[{"name":"actor","in":"query","required":true,"description":"DID of the actor who published the follow record.","schema":{"type":"string","format":"did"}},{"name":"subject","in":"query","required":true,"description":"DID named as the follow record's subject.","schema":{"type":"string","format":"did"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.graph.getFollow.output"}}}}},"x-lexicon-id":"app.certified.graph.getFollow","x-lexicon-errors":[{"name":"InvalidRequest","description":"A DID or query parameter is invalid."}]}}, + "/xrpc/app.certified.graph.listActorFollowers": {"get":{"operationId":"app_certified_graph_listActorFollowers","tags":["app.certified.graph"],"description":"Lists actors whose follow records name the requested DID as subject. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.","parameters":[{"name":"actor","in":"query","required":true,"description":"DID whose incoming follows are listed.","schema":{"type":"string","format":"did"}},{"name":"sortDirection","in":"query","required":false,"description":"Sorts by representative follow createdAt and URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum relationships per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque next-page cursor bound to sortDirection; keep the other query parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.graph.listActorFollowers.output"}}}}},"x-lexicon-id":"app.certified.graph.listActorFollowers","x-lexicon-errors":[{"name":"InvalidRequest","description":"A DID or query parameter is invalid."}]}}, + "/xrpc/app.certified.graph.listActorFollowing": {"get":{"operationId":"app_certified_graph_listActorFollowing","tags":["app.certified.graph"],"description":"Lists actors named as subjects by the requested DID's follow records. No authentication is required; duplicate relationships are collapsed before pagination, and only the returned actors are hydrated.","parameters":[{"name":"actor","in":"query","required":true,"description":"DID whose outgoing follows are listed.","schema":{"type":"string","format":"did"}},{"name":"sortDirection","in":"query","required":false,"description":"Sorts by representative follow createdAt and URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum relationships per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque next-page cursor bound to sortDirection; keep the other query parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.graph.listActorFollowing.output"}}}}},"x-lexicon-id":"app.certified.graph.listActorFollowing","x-lexicon-errors":[{"name":"InvalidRequest","description":"A DID or query parameter is invalid."}]}}, + "/xrpc/app.certified.graph.listEntityFollowers": {"get":{"operationId":"app_certified_graph_listEntityFollowers","tags":["app.certified.graph"],"description":"Lists actors following an entity AT-URI. No authentication is required; duplicate actor–entity relationships use the earliest createdAt, with URI ascending on ties. Only the returned page is hydrated: missing profile and organization sidecars are null, while lookup failures return errors rather than partial pages.","parameters":[{"name":"entity","in":"query","required":true,"description":"Full AT-URI of the followed record using a DID authority; any target collection is accepted, and matching is by URI, not CID.","schema":{"type":"string","format":"at-uri"}},{"name":"sortDirection","in":"query","required":false,"description":"Sorts by representative follow createdAt and URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum relationships per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque next-page cursor bound to sortDirection; keep the other query parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.graph.listEntityFollowers.output"}}}}},"x-lexicon-id":"app.certified.graph.listEntityFollowers","x-lexicon-errors":[{"name":"InvalidRequest","description":"The entity AT-URI or another query parameter is invalid."}]}}, + "/xrpc/app.certified.graph.listEntityFollowing": {"get":{"operationId":"app_certified_graph_listEntityFollowing","tags":["app.certified.graph"],"description":"Lists entities followed by an actor DID. No authentication is required; duplicate actor–entity relationships use the earliest createdAt, with URI ascending on ties. Only returned-page targets are hydrated and resolved to the latest indexed record by URI; missing or unsupported targets retain their URI and follow with entity null, while lookup failures return errors rather than partial pages.","parameters":[{"name":"actor","in":"query","required":true,"description":"DID whose outgoing entity follows are listed.","schema":{"type":"string","format":"did"}},{"name":"sortDirection","in":"query","required":false,"description":"Sorts by representative follow createdAt and URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum relationships per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque next-page cursor bound to sortDirection; keep the other query parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.graph.listEntityFollowing.output"}}}}},"x-lexicon-id":"app.certified.graph.listEntityFollowing","x-lexicon-errors":[{"name":"InvalidRequest","description":"The actor DID or another query parameter is invalid."}]}}, + "/xrpc/app.certified.graph.listRecentFollows": {"get":{"operationId":"app_certified_graph_listRecentFollows","tags":["app.certified.graph"],"description":"Beta query for raw account- and entity-follow records from any publisher. No authentication is required; duplicates are preserved, and before is an exclusive bound on publisher-declared createdAt. Pages are not a snapshot, so late indexing or concurrent changes may cause records to be missed.","parameters":[{"name":"before","in":"query","required":false,"description":"Exclusive upper bound on publisher-declared createdAt, not indexedAt; omit to start with the newest records.","schema":{"type":"string","format":"datetime"}},{"name":"limit","in":"query","required":false,"description":"Maximum records per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque next-page cursor; keep before unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.graph.listRecentFollows.output"}}}}},"x-lexicon-id":"app.certified.graph.listRecentFollows","x-lexicon-errors":[{"name":"InvalidRequest","description":"A datetime, limit, cursor, or query parameter is invalid."}]}}, + "/xrpc/app.certified.link.getEvmLink": {"get":{"operationId":"app_certified_link_getEvmLink","tags":["app.certified.link"],"description":"Looks up an indexed EVM-link record by exact AT-URI and hydrates its actor. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full AT-URI of an app.certified.link.evm record with a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.link.getEvmLink.output"}}}}},"x-lexicon-id":"app.certified.link.getEvmLink","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not an app.certified.link.evm record AT-URI."},{"name":"RecordNotFound","description":"No indexed EVM-link record exists at this AT-URI."}]}}, + "/xrpc/app.certified.link.listEvmLinks": {"get":{"operationId":"app_certified_link_listEvmLinks","tags":["app.certified.link"],"description":"Lists indexed EVM-link records, optionally filtered by actor DID and wallet address. Authentication is not required.","parameters":[{"name":"actors","in":"query","required":false,"description":"Actor DIDs that own matching records; values within this filter use OR.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"addresses","in":"query","required":false,"description":"EVM wallet addresses matched case-insensitively; values within this filter use OR.","schema":{"type":"array","maxItems":100,"items":{"type":"string","minLength":42,"maxLength":42}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Order by the record's createdAt timestamp and then AT-URI.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of links to return.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page, bound to sortDirection.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.link.listEvmLinks.output"}}}}},"x-lexicon-id":"app.certified.link.listEvmLinks","x-lexicon-errors":[{"name":"InvalidRequest","description":"An actor DID, EVM address, page bound, cursor, repeated scalar, or query parameter is invalid."}]}}, + "/xrpc/app.certified.location.getLocation": {"get":{"operationId":"app_certified_location_getLocation","tags":["app.certified.location"],"description":"Returns one indexed location by AT-URI; authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full location AT-URI with a DID authority; lookup matches the URI, not a CID.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.location.getLocation.output"}}}}},"x-lexicon-id":"app.certified.location.getLocation","x-lexicon-errors":[{"name":"RecordNotFound","description":"No indexed location exists at this AT-URI."}]}}, + "/xrpc/app.certified.location.listLocations": {"get":{"operationId":"app_certified_location_listLocations","tags":["app.certified.location"],"description":"Lists indexed location records; authentication is not required. Array filters use repeated unbracketed query keys; filters combine with AND, values within each array with OR, and omitted filters are unrestricted.","parameters":[{"name":"authors","in":"query","required":false,"description":"Filter by author DID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"uris","in":"query","required":false,"description":"Filter by full location AT-URI with a DID authority; matching uses the URI, not a CID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"locationTypes","in":"query","required":false,"description":"Match exact strings against locationType; empty strings are matched literally.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":20}},"style":"form","explode":true},{"name":"limit","in":"query","required":false,"description":"Page size; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque keyset cursor; keep all other parameters unchanged between pages. The cursor is bound to sortDirection, and pagination is not snapshot-isolated.","schema":{"type":"string"}},{"name":"sortDirection","in":"query","required":false,"description":"Sort by a valid zoned createdAt; otherwise indexedAt or stored row creation time, then URI, all in this direction. Defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app.certified.location.listLocations.output"}}}}},"x-lexicon-id":"app.certified.location.listLocations","x-lexicon-errors":[{"name":"InvalidRequest","description":"A query parameter is invalid, unknown, or repeated where only one value is allowed."}]}}, + "/xrpc/org.hypercerts.claim.getActivity": {"get":{"operationId":"org_hypercerts_claim_getActivity","tags":["org.hypercerts.claim"],"description":"Looks up one indexed activity by full AT-URI. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full AT-URI of the activity, using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.getActivity","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or the request includes an unsupported parameter."},{"name":"RecordNotFound","description":"No indexed activity exists at the requested URI."},{"name":"ActivityQueryFailed","description":"The activity lookup or required hydration failed."}]}}, + "/xrpc/org.hypercerts.claim.getContribution": {"get":{"operationId":"org_hypercerts_claim_getContribution","tags":["org.hypercerts.claim"],"description":"Looks up one contribution record by exact AT-URI; authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full AT-URI of the contribution record, using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.getContribution.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.getContribution","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI must identify a contribution record with a DID authority."},{"name":"RecordNotFound","description":"No indexed contribution record exists at this AT-URI."},{"name":"ContributionQueryFailed","description":"The contribution record or publisher could not be read from PostgreSQL."}]}}, + "/xrpc/org.hypercerts.claim.getContributorInformation": {"get":{"operationId":"org_hypercerts_claim_getContributorInformation","tags":["org.hypercerts.claim"],"description":"Publicly looks up one indexed contributor-information record by exact AT-URI and includes its publisher.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full contributor-information record AT-URI with a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.getContributorInformation.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.getContributorInformation","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a contributor-information record AT-URI."},{"name":"RecordNotFound","description":"No indexed contributor-information record exists at this AT-URI."},{"name":"ContributorInformationQueryFailed","description":"The record or required publisher hydration lookup failed."}]}}, + "/xrpc/org.hypercerts.claim.getRights": {"get":{"operationId":"org_hypercerts_claim_getRights","tags":["org.hypercerts.claim"],"description":"Looks up one indexed rights record by exact DID-authority AT-URI. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full AT-URI of a rights record, using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.getRights.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.getRights","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or does not identify a rights record."},{"name":"RecordNotFound","description":"No indexed rights record exists at this AT-URI."}]}}, + "/xrpc/org.hypercerts.claim.listActivities": {"get":{"operationId":"org_hypercerts_claim_listActivities","tags":["org.hypercerts.claim"],"description":"Lists indexed activities. Filters combine with AND; values within each array filter combine with OR, and duplicate values are ignored. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Filter by activity repository-owner DID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"hasOrganizationRecord","in":"query","required":false,"description":"Filter by whether the activity author has an app.certified.actor.organization/self record, regardless of profile presence.","schema":{"type":"boolean"}},{"name":"contributors","in":"query","required":false,"description":"Filter by contributor DID, including inline identities and the exact referenced contributor-information version.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"involvedActors","in":"query","required":false,"description":"Filter by activity repository-owner or contributor DID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"uris","in":"query","required":false,"description":"Filter by exact activity AT-URI; results follow the selected sort order, not input order.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort by activity createdAt, then URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum activities per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor for the next page, bound to sortDirection. Keep all other query parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.listActivities.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.listActivities","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter, sort direction, page limit, cursor, or query parameter is invalid."},{"name":"ActivityQueryFailed","description":"The activity query or required hydration failed."}]}}, + "/xrpc/org.hypercerts.claim.listContributions": {"get":{"operationId":"org_hypercerts_claim_listContributions","tags":["org.hypercerts.claim"],"description":"Lists contribution records by publisher DID, sorted by createdAt and URI; authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Repeated unbracketed publisher DIDs are ORed; use at most 100 values.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction for createdAt and URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum records in a page from 1 to 100; defaults to 25.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep filters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.listContributions.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.listContributions","x-lexicon-errors":[{"name":"InvalidRequest","description":"An author DID, sort direction, page bound, or cursor is invalid."},{"name":"ContributionQueryFailed","description":"The contribution records or publishers could not be read from PostgreSQL."}]}}, + "/xrpc/org.hypercerts.claim.listContributorInformation": {"get":{"operationId":"org_hypercerts_claim_listContributorInformation","tags":["org.hypercerts.claim"],"description":"Publicly lists indexed contributor-information records with an optional publisher-DID filter and stable createdAt ordering.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher repository DIDs; values use OR.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Direction for (createdAt, uri); defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum records in the page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep other parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.listContributorInformation.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.listContributorInformation","x-lexicon-errors":[{"name":"InvalidRequest","description":"An author DID, sort direction, page bound, cursor, repeated scalar, or query parameter is invalid."},{"name":"ContributorInformationQueryFailed","description":"The record query or required publisher hydration lookup failed."}]}}, + "/xrpc/org.hypercerts.claim.listRights": {"get":{"operationId":"org_hypercerts_claim_listRights","tags":["org.hypercerts.claim"],"description":"Lists indexed rights records with an optional publisher-DID filter. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher DIDs; repeat the unbracketed key for multiple authors. Values use OR.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Direction for the (createdAt, uri) order; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum records in the page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page; keep the sort direction unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.listRights.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.listRights","x-lexicon-errors":[{"name":"InvalidRequest","description":"An author, sort direction, page bound, cursor, repeated scalar, or query parameter is invalid."}]}}, + "/xrpc/org.hypercerts.claim.searchActivities": {"get":{"operationId":"org_hypercerts_claim_searchActivities","tags":["org.hypercerts.claim"],"description":"Searches indexed activities by a case-insensitive literal substring of title or shortDescription. Search and other filters combine with AND; values within each array filter combine with OR, and duplicate values are ignored. Authentication is not required.","parameters":[{"name":"search","in":"query","required":true,"description":"Literal, case-insensitive substring of title or shortDescription; surrounding whitespace is trimmed, and blank input applies no text filter.","schema":{"type":"string"}},{"name":"authors","in":"query","required":false,"description":"Filter by activity repository-owner DID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"hasOrganizationRecord","in":"query","required":false,"description":"Filter by whether the activity author has an app.certified.actor.organization/self record, regardless of profile presence.","schema":{"type":"boolean"}},{"name":"contributors","in":"query","required":false,"description":"Filter by contributor DID, including inline identities and the exact referenced contributor-information version.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"involvedActors","in":"query","required":false,"description":"Filter by activity repository-owner or contributor DID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"uris","in":"query","required":false,"description":"Filter by exact activity AT-URI; results follow the selected sort order, not input order.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort by activity createdAt, then URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum activities per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor for the next page, bound to sortDirection. Keep all other query parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.claim.searchActivities.output"}}}}},"x-lexicon-id":"org.hypercerts.claim.searchActivities","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter, sort direction, page limit, cursor, or query parameter is invalid."},{"name":"ActivityQueryFailed","description":"The activity query or required hydration failed."}]}}, + "/xrpc/org.hypercerts.collection.getCollection": {"get":{"operationId":"org_hypercerts_collection_getCollection","tags":["org.hypercerts.collection"],"description":"Looks up one indexed collection by exact AT-URI. Hydrates its author and exact-version location and tag sibling projections; the original collection record remains unchanged. Missing related target versions are null without hiding the collection. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full collection record AT-URI using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.output"}}}}},"x-lexicon-id":"org.hypercerts.collection.getCollection","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a collection record AT-URI."},{"name":"RecordNotFound","description":"No indexed collection exists at this AT-URI."}]}}, + "/xrpc/org.hypercerts.collection.listCollectionItems": {"get":{"operationId":"org_hypercerts_collection_listCollectionItems","tags":["org.hypercerts.collection"],"description":"Resolves one collection's embedded items in source order, one level only. Each target must match the item's exact strong-reference URI+CID; nested collections are summaries, and unavailable versions or unsupported kinds return record null. Pagination follows the latest indexed collection at the same URI across pages, even after collection changes; no version-change error or restart is required. Item additions, removals, or reordering may cause skipped or repeated results. There is no sortDirection parameter. Authentication is not required.","parameters":[{"name":"collection","in":"query","required":true,"description":"Full collection record AT-URI using a DID authority.","schema":{"type":"string","format":"at-uri"}},{"name":"limit","in":"query","required":false,"description":"Maximum embedded items in the page; default 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque item-pagination cursor. Continue with the same collection URI; it is not bound to a collection version.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.collection.listCollectionItems.output"}}}}},"x-lexicon-id":"org.hypercerts.collection.listCollectionItems","x-lexicon-errors":[{"name":"InvalidRequest","description":"The collection AT-URI, page bound, cursor, or query parameters are invalid."},{"name":"RecordNotFound","description":"No indexed collection exists at this AT-URI."}]}}, + "/xrpc/org.hypercerts.collection.listCollections": {"get":{"operationId":"org_hypercerts_collection_listCollections","tags":["org.hypercerts.collection"],"description":"Lists indexed collections. Pass array filters as repeated query parameters; filters combine with AND, while values in each array are ORed except tagUris, which requires every supplied URI. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Repository-owner DID to match.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"hasOrganizationRecord","in":"query","required":false,"description":"Filter by the author's organization/self record; false matches absence regardless of profile presence.","schema":{"type":"boolean"}},{"name":"types","in":"query","required":false,"description":"Exact collection type to match.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":64}},"style":"form","explode":true},{"name":"uris","in":"query","required":false,"description":"Match by collection record AT-URI; this does not select a CID version.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"itemUris","in":"query","required":false,"description":"Match when an embedded item's itemIdentifier.uri equals a supplied AT-URI; matching ignores CID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"tagUris","in":"query","required":false,"description":"Require every supplied vocabulary-tag AT-URI to occur in record.tags; matching ignores CID and tag records.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Direction for (createdAt, uri) ordering; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum collections per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response; use the same sortDirection.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.collection.listCollections.output"}}}}},"x-lexicon-id":"org.hypercerts.collection.listCollections","x-lexicon-errors":[{"name":"InvalidRequest","description":"A query parameter is invalid or unsupported."}]}}, + "/xrpc/org.hypercerts.collection.searchCollections": {"get":{"operationId":"org_hypercerts_collection_searchCollections","tags":["org.hypercerts.collection"],"description":"Searches collection title or shortDescription for the complete trimmed text as a case-insensitive literal substring; blank text adds no search restriction. Other filters combine with search using AND, with OR within arrays except tagUris, which requires every supplied URI. Authentication is not required.","parameters":[{"name":"search","in":"query","required":true,"description":"Case-insensitive literal substring in title or shortDescription; blank trimmed text adds no search restriction.","schema":{"type":"string"}},{"name":"authors","in":"query","required":false,"description":"Repository-owner DID to match.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"hasOrganizationRecord","in":"query","required":false,"description":"Filter by the author's organization/self record; false matches absence regardless of profile presence.","schema":{"type":"boolean"}},{"name":"types","in":"query","required":false,"description":"Exact collection type to match.","schema":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":64}},"style":"form","explode":true},{"name":"uris","in":"query","required":false,"description":"Match by collection record AT-URI; this does not select a CID version.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"itemUris","in":"query","required":false,"description":"Match when an embedded item's itemIdentifier.uri equals a supplied AT-URI; matching ignores CID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"tagUris","in":"query","required":false,"description":"Require every supplied vocabulary-tag AT-URI to occur in record.tags; matching ignores CID and tag records.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Direction for (createdAt, uri) ordering; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum collections per page; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response; use the same sortDirection.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.collection.searchCollections.output"}}}}},"x-lexicon-id":"org.hypercerts.collection.searchCollections","x-lexicon-errors":[{"name":"InvalidRequest","description":"Search text or another query parameter is invalid or unsupported."}]}}, + "/xrpc/org.hypercerts.context.getAcknowledgement": {"get":{"operationId":"org_hypercerts_context_getAcknowledgement","tags":["org.hypercerts.context"],"description":"Gets one public acknowledgement by exact AT-URI; authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Acknowledgement record AT-URI with a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.getAcknowledgement.output"}}}}},"x-lexicon-id":"org.hypercerts.context.getAcknowledgement","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or does not identify an acknowledgement record."},{"name":"RecordNotFound","description":"No acknowledgement is indexed at this AT-URI."},{"name":"AcknowledgementQueryFailed","description":"The acknowledgement or publisher lookup failed."}]}}, + "/xrpc/org.hypercerts.context.getAttachment": {"get":{"operationId":"org_hypercerts_context_getAttachment","tags":["org.hypercerts.context"],"description":"Returns the current indexed attachment at the given AT-URI with its publisher view. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"AT-URI of the attachment record, using a DID authority; lookup is by URI only, not a specific CID/version.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.getAttachment.output"}}}}},"x-lexicon-id":"org.hypercerts.context.getAttachment","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or does not identify an attachment record."},{"name":"RecordNotFound","description":"No indexed attachment was found at this AT-URI."},{"name":"AttachmentQueryFailed","description":"The attachment lookup or required publisher hydration failed."}]}}, + "/xrpc/org.hypercerts.context.getEvaluation": {"get":{"operationId":"org_hypercerts_context_getEvaluation","tags":["org.hypercerts.context"],"description":"Returns the indexed evaluation at the given AT-URI with its publisher and evaluator views. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"AT-URI of the evaluation record, using a DID authority; lookup is by URI only, not a specific CID/version.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.getEvaluation.output"}}}}},"x-lexicon-id":"org.hypercerts.context.getEvaluation","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or does not identify an evaluation record."},{"name":"RecordNotFound","description":"No indexed evaluation was found at this AT-URI."}]}}, + "/xrpc/org.hypercerts.context.getMeasurement": {"get":{"operationId":"org_hypercerts_context_getMeasurement","tags":["org.hypercerts.context"],"description":"Gets an indexed measurement by exact AT-URI and hydrates its publisher. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full measurement record AT-URI using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.getMeasurement.output"}}}}},"x-lexicon-id":"org.hypercerts.context.getMeasurement","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a measurement record AT-URI."},{"name":"RecordNotFound","description":"No indexed measurement exists at this AT-URI."}]}}, + "/xrpc/org.hypercerts.context.listAcknowledgements": {"get":{"operationId":"org_hypercerts_context_listAcknowledgements","tags":["org.hypercerts.context"],"description":"Lists public acknowledgements by publisher or subject; authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher DIDs; OR within this filter.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"subjects","in":"query","required":false,"description":"Subject record AT-URIs; matching ignores CID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction for createdAt and URI; default desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum records per page.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque next-page cursor bound to sortDirection; keep other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.listAcknowledgements.output"}}}}},"x-lexicon-id":"org.hypercerts.context.listAcknowledgements","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter value, sort direction, page bound, cursor, repeated scalar, or query parameter is invalid."},{"name":"AcknowledgementQueryFailed","description":"The acknowledgement or publisher lookup failed."}]}}, + "/xrpc/org.hypercerts.context.listAttachments": {"get":{"operationId":"org_hypercerts_context_listAttachments","tags":["org.hypercerts.context"],"description":"Lists indexed attachments with optional publisher, record URI, subject URI, and content-type filters. Values within each array filter use OR; distinct filters use AND, and duplicate values are ignored. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher repository DIDs to match.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"uris","in":"query","required":false,"description":"Attachment AT-URIs with DID authorities to include; matching uses URI only, not CID/version. Results follow sort order, not input order.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"subjects","in":"query","required":false,"description":"Match any record.subjects[].uri against these AT-URIs with DID authorities; CID values are ignored.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"contentTypes","in":"query","required":false,"description":"Exact matches on record.contentType; this is not a file MIME-type filter.","schema":{"type":"array","maxItems":100,"items":{"type":"string"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction by (createdAt, uri); defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum page size; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor tied to sortDirection; keep all other parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.listAttachments.output"}}}}},"x-lexicon-id":"org.hypercerts.context.listAttachments","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter value, cursor, sort direction, page size, or query parameter is invalid."},{"name":"AttachmentQueryFailed","description":"The attachment query or required publisher hydration failed."}]}}, + "/xrpc/org.hypercerts.context.listEvaluations": {"get":{"operationId":"org_hypercerts_context_listEvaluations","tags":["org.hypercerts.context"],"description":"Lists indexed evaluations with optional publisher, evaluator, and subject filters. Values within each array filter use OR; distinct filters use AND. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher repository DIDs to match.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"evaluators","in":"query","required":false,"description":"DIDs in any record.evaluators[].did entry, including entries beyond the hydration cap.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"subjects","in":"query","required":false,"description":"Match record.subject.uri by AT-URI with a DID authority; the reference CID is ignored.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction by (createdAt, uri); defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum page size; defaults to 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor tied to sortDirection; keep all other parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.listEvaluations.output"}}}}},"x-lexicon-id":"org.hypercerts.context.listEvaluations","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter value, cursor, sort direction, page size, or query parameter is invalid."}]}}, + "/xrpc/org.hypercerts.context.listMeasurements": {"get":{"operationId":"org_hypercerts_context_listMeasurements","tags":["org.hypercerts.context"],"description":"Lists measurements with optional publisher and subject filters. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher repository DIDs, not record.measurers.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"subjects","in":"query","required":false,"description":"Subject AT-URIs matched against record.subjects[].uri, ignoring CID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort by createdAt and URI; default desc.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum page size; default 25.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor tied to sortDirection; retain other filters between pages.","schema":{"type":"string","maxLength":8192}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.context.listMeasurements.output"}}}}},"x-lexicon-id":"org.hypercerts.context.listMeasurements","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter value, sort direction, page bound, cursor, repeated scalar, or query parameter is invalid."}]}}, + "/xrpc/org.hypercerts.entity.getFeature": {"get":{"operationId":"org_hypercerts_entity_getFeature","tags":["org.hypercerts.entity"],"description":"Looks up one indexed feature by exact AT-URI with author hydration; authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full feature record AT-URI using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.entity.getFeature.output"}}}}},"x-lexicon-id":"org.hypercerts.entity.getFeature","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a feature record AT-URI."},{"name":"RecordNotFound","description":"No indexed feature exists at this AT-URI."}]}}, + "/xrpc/org.hypercerts.entity.listFeatures": {"get":{"operationId":"org_hypercerts_entity_listFeatures","tags":["org.hypercerts.entity"],"description":"Lists indexed features with filters and direction-bound pagination; authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Repository-owner DIDs; values combine with OR.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"hasOrganizationRecord","in":"query","required":false,"description":"Whether the author has an organization self record; false is independent of profile presence.","schema":{"type":"boolean"}},{"name":"types","in":"query","required":false,"description":"Exact open-string feature types; values combine with OR.","schema":{"type":"array","maxItems":100,"items":{"type":"string","description":"Exact case-sensitive feature type.","maxLength":64}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Direction for sorting by createdAt and URI.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of features in the page.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from the previous page, bound to sortDirection.","schema":{"type":"string","maxLength":32768}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.entity.listFeatures.output"}}}}},"x-lexicon-id":"org.hypercerts.entity.listFeatures","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter, page bound, cursor, repeated scalar, or query parameter is invalid."}]}}, + "/xrpc/org.hypercerts.funding.getReceipt": {"get":{"operationId":"org_hypercerts_funding_getReceipt","tags":["org.hypercerts.funding"],"description":"Returns one indexed funding receipt and hydrates its publisher actor. Authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Funding-receipt AT-URI using a DID authority; lookup matches the URI only, not a CID.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.funding.getReceipt.output"}}}}},"x-lexicon-id":"org.hypercerts.funding.getReceipt","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a funding-receipt record AT-URI."},{"name":"RecordNotFound","description":"No indexed funding receipt exists at this AT-URI."},{"name":"ReceiptQueryFailed","description":"The receipt query or publisher hydration failed."}]}}, + "/xrpc/org.hypercerts.funding.listReceipts": {"get":{"operationId":"org_hypercerts_funding_listReceipts","tags":["org.hypercerts.funding"],"description":"Lists indexed funding receipts matching the supplied filters: filters combine with AND, while values within an array combine with OR. Repeat array parameters to supply multiple values; duplicates are ignored. Authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher repository DIDs, including facilitator, personal, and group repositories.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"uris","in":"query","required":false,"description":"Funding-receipt AT-URIs with a DID authority, matched by URI only, not CID.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"from","in":"query","required":false,"description":"Sender DIDs or full record AT-URIs with a DID authority. DIDs match only the DID variant; AT-URIs match only the strong-reference URI, not CID. Resolve handles to DIDs; invalid entries reject the request with the parameter and entry identified.","schema":{"type":"array","maxItems":100,"items":{"type":"string"}},"style":"form","explode":true},{"name":"to","in":"query","required":false,"description":"Recipient DIDs or full record AT-URIs with a DID authority. DIDs match only the DID variant; AT-URIs match only the strong-reference URI, not CID. Resolve handles to DIDs; invalid entries reject the request with the parameter and entry identified.","schema":{"type":"array","maxItems":100,"items":{"type":"string"}},"style":"form","explode":true},{"name":"forUris","in":"query","required":false,"description":"Funded-target AT-URIs with a DID authority, matched by URI only; CID is not compared.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"at-uri"}},"style":"form","explode":true},{"name":"transactionIds","in":"query","required":false,"description":"Exact transaction ID matches; values are not normalized.","schema":{"type":"array","maxItems":100,"items":{"type":"string"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Direction for ordering by createdAt then URI; defaults to desc.","schema":{"type":"string","enum":["asc","desc"]}},{"name":"limit","in":"query","required":false,"description":"Maximum receipts per page; default 25.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep all other parameters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.funding.listReceipts.output"}}}}},"x-lexicon-id":"org.hypercerts.funding.listReceipts","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter or pagination parameter is invalid."},{"name":"ReceiptQueryFailed","description":"The receipt query or publisher hydration failed."}]}}, + "/xrpc/org.hypercerts.vocab.getVocabTag": {"get":{"operationId":"org_hypercerts_vocab_getVocabTag","tags":["org.hypercerts.vocab"],"description":"Looks up one published vocabulary tag by full DID-authority AT-URI and returns its unchanged record with publisher details; authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full AT-URI of the vocabulary-tag record, using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.vocab.getVocabTag.output"}}}}},"x-lexicon-id":"org.hypercerts.vocab.getVocabTag","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid, targets another collection, or query parameters are unsupported."},{"name":"RecordNotFound","description":"No indexed vocabulary tag exists at this AT-URI."},{"name":"VocabTagQueryFailed","description":"The indexed tag or required publisher lookup failed; retry after checking the HappyView PostgreSQL service."}]}}, + "/xrpc/org.hypercerts.vocab.listVocabTags": {"get":{"operationId":"org_hypercerts_vocab_listVocabTags","tags":["org.hypercerts.vocab"],"description":"Lists published vocabulary tags by optional publisher DIDs with stable cursor pagination; authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher repository DIDs; values are ORed.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Direction for (createdAt, uri); default desc.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Page size from 1 to 100; default 25.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor; keep direction and filters unchanged between pages.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.vocab.listVocabTags.output"}}}}},"x-lexicon-id":"org.hypercerts.vocab.listVocabTags","x-lexicon-errors":[{"name":"InvalidRequest","description":"A filter value, page bound, cursor, repeated scalar, or query parameter is invalid."},{"name":"VocabTagQueryFailed","description":"The indexed tags or required publisher lookups could not be queried; retry after checking the HappyView PostgreSQL service."}]}}, + "/xrpc/org.hypercerts.workscope.getWorkscopeTag": {"get":{"operationId":"org_hypercerts_workscope_getWorkscopeTag","tags":["org.hypercerts.workscope"],"description":"Returns an indexed work-scope tag and its hydrated publisher for an exact AT-URI; authentication is not required.","parameters":[{"name":"uri","in":"query","required":true,"description":"Full work-scope-tag AT-URI using a DID authority.","schema":{"type":"string","format":"at-uri"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.workscope.getWorkscopeTag.output"}}}}},"x-lexicon-id":"org.hypercerts.workscope.getWorkscopeTag","x-lexicon-errors":[{"name":"InvalidRequest","description":"The URI is invalid or is not a work-scope-tag AT-URI."},{"name":"RecordNotFound","description":"No indexed work-scope tag exists at this AT-URI."},{"name":"WorkscopeTagQueryFailed","description":"The record lookup or publisher hydration failed."}]}}, + "/xrpc/org.hypercerts.workscope.listWorkscopeTags": {"get":{"operationId":"org_hypercerts_workscope_listWorkscopeTags","tags":["org.hypercerts.workscope"],"description":"Lists indexed work-scope tags by publisher DID with stable timestamp-and-URI ordering; authentication is not required.","parameters":[{"name":"authors","in":"query","required":false,"description":"Publisher repository DIDs; repeat this key for OR matching, up to 100 values.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"did"}},"style":"form","explode":true},{"name":"sortDirection","in":"query","required":false,"description":"Sort direction for timestamp-and-URI ordering; defaults to desc.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","required":false,"description":"Maximum page size from 1 to 100; defaults to 25.","schema":{"type":"integer","default":25,"minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor bound to sortDirection; keep other parameters unchanged between pages.","schema":{"type":"string","maxLength":8192}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/org.hypercerts.workscope.listWorkscopeTags.output"}}}}},"x-lexicon-id":"org.hypercerts.workscope.listWorkscopeTags","x-lexicon-errors":[{"name":"InvalidRequest","description":"A query parameter is invalid."},{"name":"WorkscopeTagQueryFailed","description":"The record query or publisher hydration failed."}]}} + }, + "components": { + "schemas": { + "app.certified.actor.profile.main": {"type":"record","description":"A declaration of a Certified account profile."}, + "org.hypercerts.api.defs.profileView": {"type":"object","description":"Profile record view preserving the full indexed record; indexedAt may be null when the index has no timestamp.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.actor.profile.main"}}}, + "app.certified.actor.organization.main": {"type":"record","description":"Extended metadata for an organization actor. Complements the base actor profile with organization-specific fields like legal structure and reference links."}, + "org.hypercerts.api.defs.organizationView": {"type":"object","description":"Raw organization sidecar record view preserving the full indexed record; indexedAt may be null when the index has no timestamp.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.actor.organization.main"}}}, + "app.certified.actor.getOrganization.organizationActorView": {"type":"object","description":"Actor with an indexed organization sidecar and nullable profile view.","required":["did","profile","organization"],"properties":{"did":{"type":"string","format":"did"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"},{"type":"null"}]},"organization":{"$ref":"#/components/schemas/org.hypercerts.api.defs.organizationView"}}}, + "app.certified.actor.getOrganization.output": {"type":"object","required":["actor"],"properties":{"actor":{"$ref":"#/components/schemas/app.certified.actor.getOrganization.organizationActorView"}}}, + "app.certified.actor.getOrganizations.organizationResult": {"type":"object","required":["actor","organization"],"properties":{"actor":{"type":"string","description":"Actor DID from the corresponding request occurrence.","format":"did"},"organization":{"anyOf":[{"$ref":"#/components/schemas/app.certified.actor.getOrganization.organizationActorView"},{"type":"null"}]}}}, + "app.certified.actor.getOrganizations.output": {"type":"object","required":["organizations"],"properties":{"organizations":{"type":"array","description":"One result per supplied actor occurrence, in request order.","items":{"$ref":"#/components/schemas/app.certified.actor.getOrganizations.organizationResult"}}}}, + "app.certified.actor.getProfile.output": {"type":"object","required":["profile"],"properties":{"profile":{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"}}}, + "app.certified.actor.getProfiles.profileResult": {"type":"object","required":["actor","profile"],"properties":{"actor":{"type":"string","description":"Actor DID from the corresponding request occurrence.","format":"did"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"},{"type":"null"}]}}}, + "app.certified.actor.getProfiles.output": {"type":"object","required":["profiles"],"properties":{"profiles":{"type":"array","description":"One result per supplied actor occurrence, in request order.","items":{"$ref":"#/components/schemas/app.certified.actor.getProfiles.profileResult"}}}}, + "app.certified.actor.listOrganizations.output": {"type":"object","required":["actors"],"properties":{"actors":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.actor.getOrganization.organizationActorView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "app.certified.actor.listProfiles.output": {"type":"object","required":["profiles"],"properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when pagination is complete."}}}, + "app.certified.actor.searchOrganizations.output": {"type":"object","required":["actors"],"properties":{"actors":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.actor.getOrganization.organizationActorView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "app.certified.actor.searchProfiles.output": {"type":"object","required":["profiles"],"properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when pagination is complete."}}}, + "org.hypercerts.api.defs.actorView": {"type":"object","description":"Actor DID with nullable profile and raw organization sidecar views.","required":["did","profile","organization"],"properties":{"did":{"type":"string","format":"did"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"},{"type":"null"}]},"organization":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.organizationView"},{"type":"null"}]}}}, + "app.certified.badge.award.main": {"type":"record","description":"Records a badge award to a user, project, or activity claim."}, + "app.certified.badge.definition.main": {"type":"record","description":"Defines a badge that can be awarded via badge award records to users, projects, or activity claims."}, + "app.certified.badge.getBadgeAward.badgeDefinitionRecordView": {"type":"object","description":"Exact indexed badge-definition version referenced by the award.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.badge.definition.main"}}}, + "app.certified.badge.response.main": {"type":"record","description":"Recipient response to a badge award."}, + "app.certified.badge.getBadgeAward.badgeResponseRecordView": {"type":"object","description":"Raw recipient response record without author hydration.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.badge.response.main"}}}, + "app.certified.badge.getBadgeAward.badgeAwardView": {"type":"object","description":"Badge award with its publisher, exact definition version, and recipient response status.","required":["uri","cid","indexedAt","did","author","record","badge","responseStatus","recipientResponse"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/app.certified.badge.award.main"},"badge":{"anyOf":[{"$ref":"#/components/schemas/app.certified.badge.getBadgeAward.badgeDefinitionRecordView"},{"type":"null"}]},"responseStatus":{"type":"string","description":"Latest eligible recipient response, or unanswered when none exists.","enum":["accepted","rejected","unanswered"]},"recipientResponse":{"anyOf":[{"$ref":"#/components/schemas/app.certified.badge.getBadgeAward.badgeResponseRecordView"},{"type":"null"}]}}}, + "app.certified.badge.getBadgeAward.output": {"type":"object","required":["badgeAward"],"properties":{"badgeAward":{"$ref":"#/components/schemas/app.certified.badge.getBadgeAward.badgeAwardView"}}}, + "app.certified.badge.getBadgeDefinition.badgeDefinitionView": {"type":"object","description":"Full indexed badge-definition record with its publisher actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/app.certified.badge.definition.main"}}}, + "app.certified.badge.getBadgeDefinition.output": {"type":"object","required":["badgeDefinition"],"properties":{"badgeDefinition":{"$ref":"#/components/schemas/app.certified.badge.getBadgeDefinition.badgeDefinitionView"}}}, + "app.certified.badge.getBadgeResponse.badgeResponseView": {"type":"object","description":"Raw badge response with its publisher actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/app.certified.badge.response.main"}}}, + "app.certified.badge.getBadgeResponse.output": {"type":"object","required":["badgeResponse"],"properties":{"badgeResponse":{"$ref":"#/components/schemas/app.certified.badge.getBadgeResponse.badgeResponseView"}}}, + "app.certified.badge.listBadgeAwards.output": {"type":"object","required":["badgeAwards"],"properties":{"badgeAwards":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.badge.getBadgeAward.badgeAwardView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when pagination is complete."}}}, + "app.certified.badge.listBadgeDefinitions.output": {"type":"object","required":["badgeDefinitions"],"properties":{"badgeDefinitions":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.badge.getBadgeDefinition.badgeDefinitionView"}},"cursor":{"type":"string","description":"Cursor for the next page; omitted when there are no more results."}}}, + "app.certified.badge.listBadgeResponses.output": {"type":"object","required":["badgeResponses"],"properties":{"badgeResponses":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.badge.getBadgeResponse.badgeResponseView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when pagination is complete."}}}, + "app.certified.badge.searchBadgeDefinitions.badgeDefinitionView": {"type":"object","description":"Indexed badge definition with its publisher actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/app.certified.badge.definition.main"}}}, + "app.certified.badge.searchBadgeDefinitions.output": {"type":"object","required":["badgeDefinitions"],"properties":{"badgeDefinitions":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.badge.searchBadgeDefinitions.badgeDefinitionView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when pagination is complete."}}}, + "app.certified.graph.entityFollow.main": {"type":"record","description":"Record declaring a social 'follow' relationship with a non-account entity, such as a specific record. Account (DID) follows are out of scope and belong to app.certified.graph.follow. The subject is an open union so additional non-DID entity kinds can be added in the future. Duplicate follows will be ignored by the AppView."}, + "app.certified.graph.getEntityFollow.entityFollowRecordView": {"type":"object","description":"Raw indexed entity-follow record view, including the DID that published the relationship.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.graph.entityFollow.main"}}}, + "app.certified.graph.getEntityFollow.output": {"type":"object","required":["follow"],"properties":{"follow":{"anyOf":[{"$ref":"#/components/schemas/app.certified.graph.getEntityFollow.entityFollowRecordView"},{"type":"null"}]}}}, + "app.certified.graph.follow.main": {"type":"record","description":"Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView."}, + "app.certified.graph.getFollow.followRecordView": {"type":"object","description":"Raw indexed follow record with its publisher DID. For duplicates, the earliest createdAt wins, with URI ascending on ties.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.graph.follow.main"}}}, + "app.certified.graph.getFollow.output": {"type":"object","description":"Representative raw follow record, or null if no relationship is indexed.","required":["follow"],"properties":{"follow":{"anyOf":[{"$ref":"#/components/schemas/app.certified.graph.getFollow.followRecordView"},{"type":"null"}]}}}, + "app.certified.graph.getFollow.actorFollowView": {"type":"object","description":"Displayed actor with nullable profile and organization sidecars, paired with the representative follow record.","required":["did","profile","organization","follow"],"properties":{"did":{"type":"string","format":"did"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"},{"type":"null"}]},"organization":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.organizationView"},{"type":"null"}]},"follow":{"$ref":"#/components/schemas/app.certified.graph.getFollow.followRecordView"}}}, + "app.certified.graph.listActorFollowers.output": {"type":"object","required":["followers","totalCount"],"properties":{"followers":{"type":"array","description":"Incoming relationships; each displayed DID identifies the actor who published the follow.","items":{"$ref":"#/components/schemas/app.certified.graph.getFollow.actorFollowView"}},"totalCount":{"type":"integer","description":"Count of deduplicated relationships before cursor and limit are applied.","minimum":0},"cursor":{"type":"string","description":"Next-page cursor; omitted when no more results are available."}}}, + "app.certified.graph.listActorFollowing.output": {"type":"object","required":["following","totalCount"],"properties":{"following":{"type":"array","description":"Outgoing relationships; each displayed DID identifies the actor named as the follow subject.","items":{"$ref":"#/components/schemas/app.certified.graph.getFollow.actorFollowView"}},"totalCount":{"type":"integer","description":"Count of deduplicated relationships before cursor and limit are applied.","minimum":0},"cursor":{"type":"string","description":"Next-page cursor; omitted when no more results are available."}}}, + "app.certified.graph.listEntityFollowers.entityFollowerView": {"type":"object","description":"The follower actor and the raw entity-follow record representing its relationship.","required":["did","profile","organization","follow"],"properties":{"did":{"type":"string","format":"did"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"},{"type":"null"}]},"organization":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.organizationView"},{"type":"null"}]},"follow":{"$ref":"#/components/schemas/app.certified.graph.getEntityFollow.entityFollowRecordView"}}}, + "app.certified.graph.listEntityFollowers.output": {"type":"object","required":["followers"],"properties":{"followers":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.graph.listEntityFollowers.entityFollowerView"}},"cursor":{"type":"string","description":"Next-page cursor; omitted when no more results are available."}}}, + "org.hypercerts.claim.activity.main": {"type":"record","description":"A hypercert record tracking impact work."}, + "org.hypercerts.claim.activity.contributorIdentity": {"type":"object","description":"Contributor information as a string (DID or identifier).","required":["identity"],"properties":{"identity":{"type":"string","description":"The contributor identity string (DID or identifier).","maxLength":1000,"x-lexicon-maxGraphemes":100}}}, + "com.atproto.repo.strongRef.main": {"type":"object","required":["uri","cid"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"}}}, + "org.hypercerts.claim.activity.contributorRole": {"type":"object","description":"Contribution details as a string.","required":["role"],"properties":{"role":{"type":"string","description":"The contribution role or details.","maxLength":1000,"x-lexicon-maxGraphemes":100}}}, + "org.hypercerts.claim.contributorInformation.main": {"type":"record","description":"Contributor information including identifier, display name, and image."}, + "org.hypercerts.claim.getActivity.contributorInformationView": {"type":"object","description":"Contributor-information record matched by the source reference's URI and CID; newer versions are not substituted.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/org.hypercerts.claim.contributorInformation.main"}}}, + "org.hypercerts.claim.getActivity.contributorActorView": {"type":"object","description":"Contributor DID with its current profile, if indexed.","required":["did","profile"],"properties":{"did":{"type":"string","format":"did"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"},{"type":"null"}]}}}, + "org.hypercerts.claim.getActivity.activityContributorView": {"type":"object","description":"Source contributor fields with nullable hydrated projections; unavailable referenced information or unresolved identities are null, while lookup failures fail the query.","required":["contributorIdentity","contributorInformation","actor"],"properties":{"contributorIdentity":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.claim.activity.contributorIdentity"},{"$ref":"#/components/schemas/com.atproto.repo.strongRef.main"}]},"contributionWeight":{"type":"string","maxLength":100},"contributionDetails":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.claim.activity.contributorRole"},{"$ref":"#/components/schemas/com.atproto.repo.strongRef.main"}]},"contributorInformation":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.contributorInformationView"},{"type":"null"}]},"actor":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.contributorActorView"},{"type":"null"}]}}}, + "org.hypercerts.claim.getActivity.activityView": {"type":"object","description":"Activity record with its original payload, hydrated author, and contributors only when present in the source record.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.claim.activity.main"},"contributors":{"type":"array","description":"Hydrated contributor projection in the same order and with the same multiplicity as record.contributors; omitted only when the source field is absent.","items":{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.activityContributorView"}}}}, + "org.hypercerts.collection.getCollection.collectionProfileView": {"type":"object","description":"Profile record view used in collection author projections; indexedAt is required and may be null when the index has no timestamp.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.actor.profile.main"}}}, + "org.hypercerts.collection.getCollection.collectionOrganizationView": {"type":"object","description":"Organization sidecar view used in collection author projections; indexedAt is required and may be null when the index has no timestamp.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.actor.organization.main"}}}, + "org.hypercerts.collection.getCollection.collectionActorView": {"type":"object","description":"Collection author DID with nullable profile and organization sidecar views whose indexedAt values may be null.","required":["did","profile","organization"],"properties":{"did":{"type":"string","format":"did"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionProfileView"},{"type":"null"}]},"organization":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionOrganizationView"},{"type":"null"}]}}}, + "org.hypercerts.collection.main": {"type":"record","description":"A collection/group of items (activities and/or other collections). Collections support recursive nesting."}, + "app.certified.location.main": {"type":"record","description":"A location reference"}, + "org.hypercerts.collection.getCollection.locationRecordView": {"type":"object","description":"Raw location record view with metadata and no author hydration, used for exact-version collection reference projections.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/app.certified.location.main"}}}, + "org.hypercerts.collection.getCollection.collectionLocationView": {"type":"object","description":"Original strong-reference URI and CID plus the exact referenced location record view, or null when that version is unavailable.","required":["uri","cid","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"record":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.locationRecordView"},{"type":"null"}]}}}, + "org.hypercerts.vocab.tag.main": {"type":"record","description":"A reusable vocabulary term for classifying any Hypercerts record — for example a land-cover class, a zone role, or a methodology. The vocabulary is domain-general; geospatial categories are simply its first entries. The schema carries portable term data; named vocabulary profiles decide which published terms and attachment points they recognize. Recommended record key: the deterministic form . (for example zone-role.site), as defined by the governing vocabulary profile; Lexicon validation cannot bind a record key to body fields, so writers and indexers enforce that agreement. A tag reference pins the specific version (CID) of the term that the referencing record classified against; consumers resolve the term's current status and supersession by its URI."}, + "org.hypercerts.collection.getCollection.vocabTagRecordView": {"type":"object","description":"Raw vocabulary-tag record view with metadata and no author hydration, used for exact-version collection reference projections.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"record":{"$ref":"#/components/schemas/org.hypercerts.vocab.tag.main"}}}, + "org.hypercerts.collection.getCollection.collectionTagView": {"type":"object","description":"Original strong-reference URI and CID plus the exact referenced vocabulary-tag record view, or null when that version is unavailable.","required":["uri","cid","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"record":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.vocabTagRecordView"},{"type":"null"}]}}}, + "org.hypercerts.collection.getCollection.collectionView": {"type":"object","description":"Collection record with hydrated author and exact-version location and tag projections. Missing author sidecars are null; unavailable referenced versions retain their source URI and CID with a null record. The original record is unchanged.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionActorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.collection.main"},"location":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionLocationView"},"tags":{"type":"array","description":"Projection of record.tags in source order, preserving duplicates. Present as an empty array when record.tags is empty; omitted when it is absent.","maxItems":20,"items":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionTagView"}}}}, + "org.hypercerts.entity.feature.main": {"type":"record","description":"A record for a non-agent subject that other records (measurements, evaluations, etc.) can be about, for example a land zone or an ecological stratum. It carries the subject's identity, classification, and optional published spatial representations. Geometry lives in app.certified.location records; grouping lives in org.hypercerts.collection records."}, + "org.hypercerts.collection.listCollectionItems.featureView": {"type":"object","description":"Feature record view with hydrated author actor; feature location, tag, and sameAs references remain unexpanded.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionActorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.entity.feature.main"}}}, + "app.certified.graph.listEntityFollowing.entityFollowingItem": {"type":"object","description":"An entity-follow target and its relationship record. Resolve the latest indexed target by URI; retain the URI and follow when the target is missing or unsupported.","required":["uri","entity","follow"],"properties":{"uri":{"type":"string","description":"AT-URI of the followed entity, retained even when the target cannot be resolved.","format":"at-uri"},"entity":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.activityView"},{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionView"},{"$ref":"#/components/schemas/org.hypercerts.collection.listCollectionItems.featureView"}],"description":"Resolved ActivityView, CollectionView, or author-hydrated FeatureView, or null when missing or unsupported."},{"type":"null"}]},"follow":{"$ref":"#/components/schemas/app.certified.graph.getEntityFollow.entityFollowRecordView"}}}, + "app.certified.graph.listEntityFollowing.output": {"type":"object","required":["entities"],"properties":{"entities":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.graph.listEntityFollowing.entityFollowingItem"}},"cursor":{"type":"string","description":"Next-page cursor; omitted when no more results are available."}}}, + "app.certified.graph.listRecentFollows.recentFollowView": {"type":"object","description":"Raw indexed account- or entity-follow record with its publisher DID.","required":["uri","cid","indexedAt","did","record"],"properties":{"uri":{"type":"string","description":"AT-URI of the follow record.","format":"at-uri"},"cid":{"type":"string","description":"CID of this indexed record version.","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","description":"Indexing time, or null if unavailable; ordering uses createdAt.","format":"datetime"},{"type":"null"}]},"did":{"type":"string","description":"DID of the repository that published the follow.","format":"did"},"record":{"anyOf":[{"$ref":"#/components/schemas/app.certified.graph.follow.main"},{"$ref":"#/components/schemas/app.certified.graph.entityFollow.main"}],"description":"Unmodified follow record; $type identifies its collection."}}}, + "app.certified.graph.listRecentFollows.output": {"type":"object","required":["follows"],"properties":{"follows":{"type":"array","description":"Raw records ordered by createdAt descending, then URI descending; duplicates are included.","items":{"$ref":"#/components/schemas/app.certified.graph.listRecentFollows.recentFollowView"}},"cursor":{"type":"string","description":"Next-page cursor; omitted when no more records are available."}}}, + "app.certified.link.evm.main": {"type":"record","description":"A verifiable link between an ATProto DID and an EVM wallet address, proven via a cryptographic signature. Currently supports EOA wallets via EIP-712 typed data signatures; the proof field is an open union to allow future signature methods."}, + "app.certified.link.getEvmLink.evmLinkView": {"type":"object","description":"Indexed EVM-link record with its original address and proof, and the linked actor's hydrated Certified records.","required":["uri","cid","indexedAt","did","actor","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","description":"Index timestamp, or null when the indexed row has no timestamp.","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"actor":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/app.certified.link.evm.main"}}}, + "app.certified.link.getEvmLink.output": {"type":"object","required":["evmLink"],"properties":{"evmLink":{"$ref":"#/components/schemas/app.certified.link.getEvmLink.evmLinkView"}}}, + "app.certified.link.listEvmLinks.output": {"type":"object","required":["evmLinks"],"properties":{"evmLinks":{"type":"array","items":{"$ref":"#/components/schemas/app.certified.link.getEvmLink.evmLinkView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "app.certified.location.getLocation.locationView": {"type":"object","description":"Indexed location with its original record and hydrated author.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"type":"string","format":"datetime"},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/app.certified.location.main"}}}, + "app.certified.location.getLocation.output": {"type":"object","required":["location"],"properties":{"location":{"$ref":"#/components/schemas/app.certified.location.getLocation.locationView"}}}, + "app.certified.location.listLocations.output": {"type":"object","required":["locations"],"properties":{"locations":{"type":"array","description":"Matching location records in page order.","items":{"$ref":"#/components/schemas/app.certified.location.getLocation.locationView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.claim.getActivity.output": {"type":"object","required":["activity"],"properties":{"activity":{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.activityView"}}}, + "org.hypercerts.claim.contribution.main": {"type":"record","description":"Details about a specific contribution including role, description, and timeframe."}, + "org.hypercerts.claim.getContribution.contributionView": {"type":"object","description":"Contribution record view with a hydrated publisher and unchanged source record; the publisher is not necessarily the contributor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.claim.contribution.main"}}}, + "org.hypercerts.claim.getContribution.output": {"type":"object","required":["contribution"],"properties":{"contribution":{"$ref":"#/components/schemas/org.hypercerts.claim.getContribution.contributionView"}}}, + "org.hypercerts.claim.getContributorInformation.contributorInformationView": {"type":"object","description":"Contributor-information record with its full source payload and hydrated publishing actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.claim.contributorInformation.main"}}}, + "org.hypercerts.claim.getContributorInformation.output": {"type":"object","required":["contributorInformation"],"properties":{"contributorInformation":{"$ref":"#/components/schemas/org.hypercerts.claim.getContributorInformation.contributorInformationView"}}}, + "org.hypercerts.claim.rights.main": {"type":"record","description":"Describes the rights that a contributor and/or an owner has, such as whether the hypercert can be sold, transferred, and under what conditions."}, + "org.hypercerts.claim.getRights.rightsView": {"type":"object","description":"Rights record with its publisher actor; the full record is preserved and attachments are not expanded.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.claim.rights.main"}}}, + "org.hypercerts.claim.getRights.output": {"type":"object","required":["rights"],"properties":{"rights":{"$ref":"#/components/schemas/org.hypercerts.claim.getRights.rightsView"}}}, + "org.hypercerts.claim.listActivities.output": {"type":"object","required":["activities"],"properties":{"activities":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.activityView"}},"cursor":{"type":"string","description":"Next-page cursor; absent when pagination is complete."}}}, + "org.hypercerts.claim.listContributions.output": {"type":"object","required":["contributions"],"properties":{"contributions":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.claim.getContribution.contributionView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted after the last page."}}}, + "org.hypercerts.claim.listContributorInformation.output": {"type":"object","required":["contributorInformation"],"properties":{"contributorInformation":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.claim.getContributorInformation.contributorInformationView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.claim.listRights.output": {"type":"object","required":["rights"],"properties":{"rights":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.claim.getRights.rightsView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.claim.searchActivities.output": {"type":"object","required":["activities"],"properties":{"activities":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.activityView"}},"cursor":{"type":"string","description":"Next-page cursor; absent when pagination is complete."}}}, + "org.hypercerts.collection.getCollection.output": {"type":"object","required":["collection"],"properties":{"collection":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionView"}}}, + "org.hypercerts.collection.listCollectionItems.collectionSummaryView": {"type":"object","description":"Non-recursive summary of a collection item target.","required":["uri","cid","did","title"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"did":{"type":"string","format":"did"},"type":{"type":"string","maxLength":64},"title":{"type":"string","maxLength":800,"x-lexicon-maxGraphemes":80},"shortDescription":{"type":"string","maxLength":3000,"x-lexicon-maxGraphemes":300}}}, + "org.hypercerts.collection.listCollectionItems.collectionItemView": {"type":"object","description":"One embedded collection item in source order, retaining its original strong reference and optional weight. Resolve only an exact URI+CID target one level deep; nested collections use a summary, and unavailable versions or unsupported kinds produce record null.","required":["itemIdentifier","record"],"properties":{"itemIdentifier":{"$ref":"#/components/schemas/com.atproto.repo.strongRef.main"},"itemWeight":{"type":"string","maxLength":100},"record":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.claim.getActivity.activityView"},{"$ref":"#/components/schemas/org.hypercerts.collection.listCollectionItems.collectionSummaryView"},{"$ref":"#/components/schemas/org.hypercerts.collection.listCollectionItems.featureView"}],"description":"Resolved ActivityView, CollectionSummaryView, or FeatureView using the item strong reference's exact URI+CID; otherwise null."},{"type":"null"}]}}}, + "org.hypercerts.collection.listCollectionItems.output": {"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.collection.listCollectionItems.collectionItemView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.collection.listCollections.output": {"type":"object","required":["collections"],"properties":{"collections":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionView"}},"cursor":{"type":"string","description":"Cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.collection.searchCollections.output": {"type":"object","required":["collections"],"properties":{"collections":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.collection.getCollection.collectionView"}},"cursor":{"type":"string","description":"Cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.context.acknowledgement.main": {"type":"record","description":"Acknowledges a record (subject) or its relationship in a context. Created in the acknowledging actor's repo to form a bidirectional link. Examples: a contributor acknowledging inclusion in an activity, an activity owner acknowledging inclusion in a collection, or a record owner acknowledging an evaluation."}, + "org.hypercerts.api.defs.acknowledgementView": {"type":"object","description":"Acknowledgement record with its publisher actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.context.acknowledgement.main"}}}, + "org.hypercerts.context.getAcknowledgement.output": {"type":"object","required":["acknowledgement"],"properties":{"acknowledgement":{"$ref":"#/components/schemas/org.hypercerts.api.defs.acknowledgementView"}}}, + "org.hypercerts.context.attachment.main": {"type":"record","description":"An attachment providing commentary, context, evidence, or documentary material related to a hypercert record (e.g. an activity, project, claim, or evaluation)."}, + "org.hypercerts.context.getAttachment.attachmentView": {"type":"object","description":"Attachment with its hydrated publisher and unchanged source record; subject, content, and location references are not expanded, and external files are not fetched. Missing publisher sidecars are null; query or hydration failures fail the request.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.context.attachment.main"}}}, + "org.hypercerts.context.getAttachment.output": {"type":"object","required":["attachment"],"properties":{"attachment":{"$ref":"#/components/schemas/org.hypercerts.context.getAttachment.attachmentView"}}}, + "org.hypercerts.context.evaluation.main": {"type":"record","description":"An evaluation of a hypercert record (e.g. an activity and its impact)."}, + "org.hypercerts.context.getEvaluation.hydratedEvaluationEvaluatorView": {"type":"object","description":"An original evaluator entry with its profile and organization sidecars looked up.","required":["did","hydrationStatus","profile","organization"],"properties":{"did":{"type":"string","format":"did"},"hydrationStatus":{"type":"string","const":"hydrated"},"profile":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.profileView"},{"type":"null"}]},"organization":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.api.defs.organizationView"},{"type":"null"}]}}}, + "org.hypercerts.context.getEvaluation.omittedEvaluationEvaluatorView": {"type":"object","description":"An original evaluator entry not hydrated.","required":["did","hydrationStatus"],"properties":{"did":{"type":"string","format":"did"},"hydrationStatus":{"type":"string","const":"omitted"}}}, + "org.hypercerts.context.getEvaluation.evaluationView": {"type":"object","description":"Evaluation with the complete original record, hydrated publisher, and evaluator views. For hydrated actors, missing profile or organization sidecars are null; query or hydration failures fail the request.","required":["uri","cid","indexedAt","did","author","record","evaluators"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"type":"string","format":"datetime"},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.context.evaluation.main"},"evaluators":{"type":"array","description":"One-for-one projection of record.evaluators, preserving source order, duplicates, and entry fields. Entries after position 100 remain present with hydrationStatus \"omitted\" and no profile or organization.","maxItems":1000,"items":{"anyOf":[{"$ref":"#/components/schemas/org.hypercerts.context.getEvaluation.hydratedEvaluationEvaluatorView"},{"$ref":"#/components/schemas/org.hypercerts.context.getEvaluation.omittedEvaluationEvaluatorView"}]}}}}, + "org.hypercerts.context.getEvaluation.output": {"type":"object","required":["evaluation"],"properties":{"evaluation":{"$ref":"#/components/schemas/org.hypercerts.context.getEvaluation.evaluationView"}}}, + "org.hypercerts.context.measurement.main": {"type":"record","description":"Measurement data related to one or more records (e.g. activities, projects, etc.)."}, + "org.hypercerts.context.getMeasurement.measurementView": {"type":"object","description":"Indexed measurement with its publisher actor and original record.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.context.measurement.main"}}}, + "org.hypercerts.context.getMeasurement.output": {"type":"object","required":["measurement"],"properties":{"measurement":{"$ref":"#/components/schemas/org.hypercerts.context.getMeasurement.measurementView"}}}, + "org.hypercerts.context.listAcknowledgements.output": {"type":"object","required":["acknowledgements"],"properties":{"acknowledgements":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.api.defs.acknowledgementView"}},"cursor":{"type":"string","description":"Omitted when there is no next page."}}}, + "org.hypercerts.context.listAttachments.output": {"type":"object","required":["attachments"],"properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.context.getAttachment.attachmentView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.context.listEvaluations.output": {"type":"object","required":["evaluations"],"properties":{"evaluations":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.context.getEvaluation.evaluationView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.context.listMeasurements.output": {"type":"object","required":["measurements"],"properties":{"measurements":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.context.getMeasurement.measurementView"}},"cursor":{"type":"string","description":"Next-page cursor; omitted when no page follows.","maxLength":8192}}}, + "org.hypercerts.entity.defs.featureView": {"type":"object","description":"Indexed feature record with its hydrated author actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.entity.feature.main"}}}, + "org.hypercerts.entity.getFeature.output": {"type":"object","required":["feature"],"properties":{"feature":{"$ref":"#/components/schemas/org.hypercerts.entity.defs.featureView"}}}, + "org.hypercerts.entity.listFeatures.output": {"type":"object","required":["features"],"properties":{"features":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.entity.defs.featureView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.funding.receipt.main": {"type":"record","description":"Records a funding receipt for a payment from one user to another user. It may be recorded by the recipient, by the sender, or by a third party. The sender may remain anonymous."}, + "org.hypercerts.funding.getReceipt.receiptView": {"type":"object","description":"Funding receipt with its publisher actor hydrated; the indexed record is unchanged, including its decimal-string amount, and party and funded-target references are not expanded. Missing publisher profile or organization sidecars are null; indexedAt is null when the index has no timestamp. A receipt is not proof of payment.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.funding.receipt.main"}}}, + "org.hypercerts.funding.getReceipt.output": {"type":"object","required":["receipt"],"properties":{"receipt":{"$ref":"#/components/schemas/org.hypercerts.funding.getReceipt.receiptView"}}}, + "org.hypercerts.funding.listReceipts.output": {"type":"object","required":["receipts"],"properties":{"receipts":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.funding.getReceipt.receiptView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, + "org.hypercerts.vocab.getVocabTag.vocabTagView": {"type":"object","description":"Vocabulary-tag record with its unchanged source and hydrated publisher actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.vocab.tag.main"}}}, + "org.hypercerts.vocab.getVocabTag.output": {"type":"object","required":["vocabTag"],"properties":{"vocabTag":{"$ref":"#/components/schemas/org.hypercerts.vocab.getVocabTag.vocabTagView"}}}, + "org.hypercerts.vocab.listVocabTags.output": {"type":"object","required":["vocabTags"],"properties":{"vocabTags":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.vocab.getVocabTag.vocabTagView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when pagination is complete."}}}, + "org.hypercerts.workscope.tag.main": {"type":"record","description":"A reusable scope atom for work scope logic expressions. Scopes can represent topics, languages, domains, deliverables, methods, regions, tags, or other categorical labels. Tags are composed into structured expressions via CEL (Common Expression Language) on activity records."}, + "org.hypercerts.workscope.getWorkscopeTag.workscopeTagView": {"type":"object","description":"Work-scope tag view with its hydrated publisher, unchanged record, and nullable index timestamp.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.workscope.tag.main"}}}, + "org.hypercerts.workscope.getWorkscopeTag.output": {"type":"object","required":["workscopeTag"],"properties":{"workscopeTag":{"$ref":"#/components/schemas/org.hypercerts.workscope.getWorkscopeTag.workscopeTagView"}}}, + "org.hypercerts.workscope.listWorkscopeTags.output": {"type":"object","required":["workscopeTags"],"properties":{"workscopeTags":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/org.hypercerts.workscope.getWorkscopeTag.workscopeTagView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when no next page exists."}}} + } + } +} diff --git a/.agents/skills/hypercerts-api/references/recipes.md b/.agents/skills/hypercerts-api/references/recipes.md new file mode 100644 index 0000000..46ce213 --- /dev/null +++ b/.agents/skills/hypercerts-api/references/recipes.md @@ -0,0 +1,41 @@ +# Consumer workflow recipes + +These recipes show endpoint choice and the data to carry between calls. For exact parameters, response fields, cursor rules, or declared errors, inspect the corresponding operation and schemas in the [bundled OpenAPI contract](openapi.json). + +## Search or list activities + +1. **Choose by the question.** Use `org.hypercerts.claim.searchActivities` for a text search. Its required `search` is currently a case-insensitive literal substring of title or short description. Use `org.hypercerts.claim.listActivities` when the task is structured discovery by author, contributor, involved actor, URI, or organization-record presence and does not need text matching. +2. **Use the correct actor role.** `authors` means the activity repository-owner DID; `contributors` filters contributor DIDs; `involvedActors` has its own combined meaning. Do not substitute one because the same DID appears in the record. +3. **Build a bounded page.** Send a moderate `limit` and the exact filters/sort documented for that operation. Array-valued filters use repeated unbracketed query keys where declared. Search/filter combination and array OR/AND semantics are operation-specific. +4. **Continue consistently.** If the response includes a cursor, carry it forward with the same search, all filters, and sort direction. Stop when the cursor is omitted. A changed filter or direction starts a new traversal; do not attach an old cursor to a new query. +5. **Use a detail call only when needed.** A returned activity includes its URI/CID and hydrated view. For a later exact lookup, pass its AT-URI to `org.hypercerts.claim.getActivity`. + +**Likely failure modes:** `search` is required even if the client wants a text search; invalid filters/cursors are not “no results”; a required hydration/query failure can fail the operation rather than produce a partial activity list. A missing exact activity from `getActivity` is distinct from an empty list. Check the operation's declared error codes and see [reliability.md](reliability.md). + +## Load exact collection item versions + +1. If the collection URI is known, optionally load its current indexed view with `org.hypercerts.collection.getCollection` and retain the collection AT-URI. Do not treat that URI as a CID-pinned collection version. +2. Call `org.hypercerts.collection.listCollectionItems` with `collection=` and a bounded `limit`. It follows the collection's embedded item order; there is no `sortDirection` parameter. +3. Preserve each item's `itemIdentifier.uri` **and** `itemIdentifier.cid`. This strong reference identifies the intended item version. Consume the resolved `record` only as that exact version; do not replace a null result with a newer record found by URI alone. +4. `record` may be null when the exact version is unavailable or the kind is unsupported. Nested collections are returned as one-level summaries, not recursively expanded. A null resolution is a valid item result, not necessarily a failed page. +5. For another page, reuse the same collection URI and cursor. The cursor follows the latest indexed collection at that URI across pages, not a pinned collection version. If the collection changes, item additions/removals/reordering can cause repeats or skips; the endpoint does not promise snapshot pagination. + +**Likely failure modes:** passing a record URI where the required collection URI belongs; discarding CID and accidentally displaying a different version; assuming nested collections are expanded; or assuming pages represent one immutable collection snapshot. Inspect `org.hypercerts.collection.listCollectionItems` and `org.hypercerts.collection.getCollection` in the [bundled OpenAPI contract](openapi.json) before relying on resolution details. + +## Load profile and organization context + +1. For one actor profile, call `app.certified.actor.getProfile` with a DID or handle. For many known actor DIDs, use `app.certified.actor.getProfiles` with repeated `actors` values; the returned results correspond to the input occurrences and `profile` can be null. +2. For organization sidecar context, use `app.certified.actor.getOrganization` with an actor DID or batch known DIDs with `app.certified.actor.getOrganizations`. In batch results, an absent organization is represented by a null `organization` for that actor. The organization actor view's `profile` may independently be null. +3. Use `listProfiles` / `listOrganizations` to browse and the corresponding `search...` endpoint for text discovery. Do not try to resolve handles in the batch APIs: their contract is DID input. `getProfile` handle resolution depends on the configured resolver and is not independent DID-document verification. +4. When another endpoint already returns an author/actor view, inspect that view's contract before issuing a second hydration call. Optional profile or organization projections can be null; fetching the full view again may add work without making the indexed data fresher. + +**Likely failure modes:** treating no indexed profile as an invalid DID, interpreting a missing organization sidecar as a missing actor, assuming profile and organization presence move together, or treating handle resolution failure as proof that the actor has no profile. See [reliability.md](reliability.md) for the distinction between null, not-found, and query failure. + +## Read badge award response status + +1. For one known award, call `app.certified.badge.getBadgeAward` with the award's full AT-URI. The `badgeAward` view exposes `responseStatus`: `accepted`, `rejected`, or `unanswered`. +2. Treat `unanswered` as a successful award with no eligible response in the indexed view. Its `recipientResponse` is nullable. A missing badge definition projection (`badge: null`) is separate from response status. +3. When discovering multiple awards, use `app.certified.badge.listBadgeAwards` and its documented filters/page rules; status is part of those award views. Use `app.certified.badge.getBadgeResponse` for one known raw response URI or `app.certified.badge.listBadgeResponses` to inspect raw responses, optionally filtering by award AT-URI. +4. Do not infer an award's derived status solely from whichever raw response records happen to be in a partial page. `getBadgeAward` is the direct status surface; its exact latest-eligible-response rule is defined in the bundled OpenAPI operation. + +**Likely failure modes:** confusing `RecordNotFound` for the award with `unanswered`; assuming a raw response list is a status summary; or treating a null definition projection as a rejected/unanswered response. Inspect `app.certified.badge.getBadgeAward` and `app.certified.badge.listBadgeResponses` in the [bundled OpenAPI contract](openapi.json) for their exact parameters, response fields, and declared errors. diff --git a/.agents/skills/hypercerts-api/references/reliability.md b/.agents/skills/hypercerts-api/references/reliability.md new file mode 100644 index 0000000..5536f82 --- /dev/null +++ b/.agents/skills/hypercerts-api/references/reliability.md @@ -0,0 +1,43 @@ +# Identity, freshness, nulls, and errors + +## Keep actor, record, and version identity distinct + +- **DID** (`did:...`) identifies an actor/repository. Actor filters and some `actor` parameters expect DIDs; check each schema. In record views, `did` is commonly the publisher/repository DID, not a version identifier. +- **AT-URI** (`at:////`) identifies a record location. It is the input for many `uri` parameters and may identify the current indexed version at that location; it does not pin a particular content version. +- **CID** identifies record content at a version. A strong reference carries both URI and CID. Preserve both when the source contract uses a strong reference. + +A handle is a resolvable actor identifier, not a DID or record URI. `app.certified.actor.getProfile` accepts a DID or handle and uses the configured handle resolver; the declared contract does not claim independent DID-document verification. Batch profile/organization lookups take DIDs. + +### Exact collection item versions + +`org.hypercerts.collection.listCollectionItems` resolves each embedded item's strong reference by exact URI **and** CID. If the requested CID is unavailable, the item's `record` can be null; do not silently substitute a newer record at the same URI. Nested collections are summaries, not recursive expansion. By contrast, collection discovery filters such as `itemUris` and `tagUris` currently match AT-URIs without selecting a CID version. See [recipes.md](recipes.md#load-exact-collection-item-versions) and the operation's details in the bundled OpenAPI contract before relying on exact-version behavior. + +## Indexed data is not a live repository read + +Queries return indexed public data. Do not promise immediate visibility after a record changes, infer that the absence of an indexed row proves that no source record exists, or assume pages share a database snapshot. `indexedAt` may be nullable even when the field is required in a view. + +For a potentially fresh record that is absent: + +1. Validate the input kind and authority (DID vs AT-URI), then check the exact endpoint's required parameters and declared errors in the bundled OpenAPI contract. +2. Distinguish a successful empty list or nullable projection from a failed exact lookup. If the application expects newly indexed data, use a bounded retry/backoff or show a pending/stale state rather than claiming certainty. +3. Keep a cursor with the query that produced it. Repeating or changing filters can produce different pages; some operations explicitly document non-snapshot or mutable-source behavior. For example, collection-item pagination follows the latest indexed collection at that URI and can repeat/skip items if it changes; the recent-follows feed also documents non-snapshot behavior. +4. The bundled contract snapshot describes declared behavior, not a specific deployment version or index freshness. Use the API directly when the task needs live indexed results; do not send unrelated availability probes. A deployment-specific availability check requires explicit approval for the target. + +## Null, omitted, empty, not-found, and failure are different + +- **Null field:** the endpoint returned a known enclosing result, but one optional or nullable projection is unavailable/absent under that contract. Examples include a null profile in batch `getProfiles`, a null organization in `getOrganizations`, a null `follow` in `getFollow`, or a null resolved collection-item `record`. Preserve and render this state intentionally. +- **Omitted optional field:** the schema does not require the property in that condition. Do not treat omission as the same representation as explicit null unless the exact endpoint contract says so. +- **Empty list:** the query succeeded and returned no matching items. It is not the same as an invalid query or failed hydration. +- **Not-found error:** a `get...` query may declare `RecordNotFound` when no matching record is indexed. That is not necessarily a successful response containing a null record. Use the endpoint's own declared error contract. +- **Query/hydration error:** an operation may fail if required indexed data cannot be queried or hydrated. Do not hide it by returning an empty list or null unless the endpoint explicitly defines that behavior. +- **Domain status:** `getBadgeAward` can return a valid award with `responseStatus: "unanswered"` and `recipientResponse: null`. That is neither a not-found error nor a failed request. The award view can separately have `badge: null` if its definition projection is unavailable. + +A nullable actor profile does not imply an invalid DID; a missing organization sidecar does not prove the actor is missing; an unavailable exact CID does not prove another version at that URI is absent. + +## Diagnose failures without overgeneralizing + +1. Record HTTP status and parse the JSON XRPC error code/message when present; preserve a fallback for empty or non-JSON bodies. See [request-patterns.md](request-patterns.md#handle-http-and-xrpc-errors). +2. Inspect the exact endpoint's declared errors in the bundled [OpenAPI contract](openapi.json). `InvalidRequest`, `RecordNotFound`, resolver errors, and query/hydration errors indicate different next steps; don't assume every endpoint declares the same codes or status mapping. +3. For `InvalidRequest`, verify full NSID path, parameter names, encoding, required values, array limits, type/format, cursor, and sort/filter preservation. +4. For a not-found or empty result, verify the identifier is the expected DID/AT-URI and consider index freshness. Do not silently downgrade a failure into absence. +5. The bundled snapshot cannot establish that an endpoint is enabled on the selected host. If deployment availability itself is the user's request, make only a scoped check against the explicitly approved target; otherwise, do not infer availability from the contract or probe the host. diff --git a/.agents/skills/hypercerts-api/references/request-patterns.md b/.agents/skills/hypercerts-api/references/request-patterns.md new file mode 100644 index 0000000..7d4364e --- /dev/null +++ b/.agents/skills/hypercerts-api/references/request-patterns.md @@ -0,0 +1,109 @@ +# Request construction, filters, and pagination + +## Build one public XRPC GET + +Every query is `GET /xrpc/` on either base URL in the parent [`SKILL.md`](../SKILL.md). Encode every argument in the query string. Do not send a request body or credentials. + +```ts +const apiBase = "https://api.hypercerts.dev"; // choose the approved target for your app +const params = new URLSearchParams(); +params.set("search", "forest restoration"); +params.set("sortDirection", "desc"); +params.set("limit", "25"); + +const authors = ["did:plc:author-one", "did:plc:author-two"]; +for (const author of authors) params.append("authors", author); + +const url = new URL( + `/xrpc/org.hypercerts.claim.searchActivities?${params.toString()}`, + apiBase, +); +// When the application runs this URL, use GET and no Authorization header. +``` + +`URL` and `URLSearchParams` handle percent-encoding of spaces, colons, slashes, and other reserved characters. Do not concatenate raw user input into a URL. Do not add `Authorization`, OAuth, API-key, or login parameters: queries are public and read-only. + +## Encode arrays only as their endpoint contract specifies + +For array query parameters documented with form/explode in the bundled OpenAPI operation, append the same **unbracketed** key once per value: + +```ts +params.append("authors", authorDid1); +params.append("authors", authorDid2); +// Result includes authors=...&authors=..., URL-encoded by URLSearchParams. +``` + +Do not use `authors[]=` or comma-joined values unless that exact endpoint contract says to. Omit an optional array when it has no values rather than sending a guessed encoding. Some queries have no array parameters, and not every endpoint accepts the same arrays. Check the operation's parameters and schemas in the [bundled OpenAPI contract](openapi.json) for item formats, requiredness, maximum array size, and semantics. + +A useful starting distinction: arrays often mean “any of these” for a filter, while separate filters may combine with AND, but this is **not a universal rule**. For example, the bundled collection contract says `tagUris` requires every supplied tag URI, while `itemUris` matches URI without CID. Confirm the exact operation before relying on filter logic. + +## Keep page requests cursor-consistent + +For a list/search operation whose output has a cursor, keep a base set of all non-cursor parameters and replace only the cursor on continuation. Preserve repeated array values, filters, `search`, `limit`, and `sortDirection` exactly. The example below is illustrative; verify the chosen endpoint's cursor binding and response-array name. + +```ts +const baseParams = new URLSearchParams(); +baseParams.append("authors", authorDid1); +baseParams.append("authors", authorDid2); +baseParams.set("sortDirection", "desc"); +baseParams.set("limit", "25"); + +let cursor: string | undefined; +for (;;) { + const pageParams = new URLSearchParams(baseParams); + if (cursor !== undefined) pageParams.set("cursor", cursor); + + const url = new URL( + `/xrpc/org.hypercerts.claim.listActivities?${pageParams.toString()}`, + apiBase, + ); + // Fetch/decode the page in the application; each call remains a GET. + const page = await fetchActivityPage(url); + consume(page.activities); + + if (page.cursor === undefined) break; + cursor = page.cursor; +} +``` + +Treat cursors as opaque. Do not decode, synthesize, or reuse one after changing a filter/sort. A changed query begins at page one. Use a bounded `limit`; the bundled contract shows many list queries allow 1–100 and default to 25, but check the exact schema instead of assuming those bounds apply universally. Page stability is endpoint-specific; a cursor does not imply snapshot isolation. + +## Interpret filters per operation + +- Check whether a parameter is required. Search endpoints often require `search`; list endpoints may omit all filters. +- Check the type/format: a `DID`, handle, AT-URI, boolean, enum, and arbitrary string are not interchangeable. +- Check sort defaults and which values bind the cursor. Preserve the chosen direction on subsequent pages. +- Read the exact endpoint's prose for trimming, literal vs token search, case sensitivity, duplicate handling, and AND/OR behavior. Never transfer these assumptions from a neighboring endpoint. + +The compact [endpoint map](endpoint-map.md) helps choose an operation; exact query parameters and response schemas are in the [bundled OpenAPI contract](openapi.json). + +## Handle HTTP and XRPC errors + +Keep the HTTP status even when the response body is missing or not JSON. Parse a JSON body when available and surface the XRPC `error` code and `message` if present; do not treat every failure as an empty result or assume all endpoint errors map to the same status. + +```ts +const response = await fetch(url, { + method: "GET", + headers: { Accept: "application/json" }, +}); +const text = await response.text(); +let payload: unknown; +try { + payload = text ? JSON.parse(text) : undefined; +} catch { + payload = undefined; // retain HTTP status; body was not usable JSON +} + +if (!response.ok) { + const body = payload && typeof payload === "object" + ? payload as Record + : {}; + const code = typeof body.error === "string" ? body.error : "XrpcError"; + const message = typeof body.message === "string" ? body.message : ""; + throw new Error( + `GET ${url.pathname} failed: HTTP ${response.status}, ${code}${message ? `: ${message}` : ""}`, + ); +} +``` + +On failure, use that endpoint's declared errors in the bundled OpenAPI operation to decide whether the request is invalid, a record is absent from the index, handle resolution failed, or an indexed query/hydration failed. Do not map a query failure to “no results.” For null and not-found distinctions, see [reliability.md](reliability.md). diff --git a/AGENTS.md b/AGENTS.md index 0893b38..b3844d1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ - Use the repository-pinned pnpm version and preserve the lockfile. - Treat `api/manifest.json` as authoritative for the API modules included in this checkout. -- For API endpoint or contract changes, review the user-facing docs as part of the change. This includes the endpoint explorer in `docs/`; keep its committed Lexicon/OpenAPI snapshots and coverage metadata aligned with `api/manifest.json`, module manifests, and handler behavior, and update explorer tests when relevant. +- For API endpoint, contract, or externally visible query-behavior changes, review the user-facing docs and update `.agents/skills/hypercerts-api/` in the same change. This includes the endpoint explorer in `docs/`; keep its committed Lexicon/OpenAPI snapshots and coverage metadata aligned with `api/manifest.json`, module manifests, and handler behavior, and update explorer tests when relevant. Keep the skill's bundled OpenAPI snapshot, endpoint map, and relevant consumer guidance aligned too; because the skill is distributed without this repository, keep its references self-contained and free of repo-relative contract links. - Read [CONTRIBUTING.md](CONTRIBUTING.md) for local validation and HTTP runtime test requirements before changing test or installer behavior. - `pnpm install:api` sends admin requests to a HappyView instance and uploads assets. Do not run it unless the user explicitly approves the target and token in the current conversation. - HTTP runtime tests use a task-owned local Compose project and disposable database. Do not target or tear down unrelated services; note that the Compose bridge network permits egress and the configured proxy is not network-level isolation. diff --git a/docs/README.md b/docs/README.md index a95ab7c..201c18f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,7 +18,7 @@ Open . The explorer defaults to `https://api.test.hyperce To offer named servers, set `VITE_HAPPYVIEW_SERVERS` when starting the dev server or building the site: ```sh -VITE_HAPPYVIEW_SERVERS='[{"label":"Staging","url":"https://staging.api.hypercerts.dev"},{"label":"Test","url":"https://test.api.hypercerts.dev"}]' pnpm docs:dev +VITE_HAPPYVIEW_SERVERS='[{"label":"Staging","url":"https://api.staging.hypercerts.dev"},{"label":"Test","url":"https://test.api.hypercerts.dev"},{"label":"Production","url":"https://api.hypercerts.dev"}]' pnpm docs:dev ``` The value must be a nonempty JSON array of labeled, distinct http(s) base URLs without credentials, query, or fragment. The first entry is the default; Local and Custom remain available. These URLs are public in the browser bundle, so do not include secrets. Changing a deployed site's configuration requires a rebuild and redeploy.