Monorepo boundaries and rollout guidance for external consumer repositories using the Legaciti integrations API.
Ownership boundaries
Section titled “Ownership boundaries”This monorepo owns:
- the
/integrations/v1runtime inworkers/consumer-api - the canonical integrations contract in
packages/api-contract - installation, credential, origin verification, and audit control-plane flows in
apps/dashboard - integrations documentation in
apps/docs - contract, runtime, and resilience checks under
tests/
This monorepo does not own:
- WordPress plugin implementation
- Drupal module implementation
- consumer SDK implementations
Those consumers should live in separate repositories and integrate against the published API contract and documentation from this repo.
Coordination contract for external consumers
Section titled “Coordination contract for external consumers”External consumer repositories should treat these artifacts as canonical:
- OpenAPI source:
packages/api-contract/src/integrations.openapi.ts - generated docs:
/reference/integrations-api - runtime base path:
/integrations/v1 - auth header:
X-API-Key - contract validation lanes:
pnpm test:integrations:contract,pnpm test:integrations:runtime,pnpm test:integrations:resilience
If an external consumer needs a new capability, update the contract and runtime here first, then update downstream consumer repositories.
Rollout guidance
Section titled “Rollout guidance”- Add or change the integrations contract in
packages/api-contract. - Implement matching runtime behavior in
workers/consumer-apiand dashboard control-plane flows if needed. - Regenerate docs and update migration notes in this repo.
- Run the integrations contract/runtime/resilience suites.
- Only after the API surface is stable should external consumer repositories update their implementations.
Reference runbook: /docs/runbooks/integrations-api-rollout.md
This keeps the API contract authoritative and prevents individual consumer repositories from drifting into undocumented behavior.
Migration guidance for existing consumers
Section titled “Migration guidance for existing consumers”Consumers still using legacy public API key flows should migrate to installation-scoped credentials:
- Create an installation in the dashboard.
- Register one or more origins for that installation.
- Complete origin verification.
- Issue an installation credential and scope it to the minimum required read capabilities.
- Update the external consumer repository to call
/integrations/v1withX-API-Key. - Verify the new flow with the contract and runtime checks before removing legacy credentials.
Recommended migration posture:
- run old and new consumers in parallel for a short validation window when possible
- migrate one installation at a time
- keep credentials scoped narrowly during rollout
- monitor dashboard audit history for scope denials, origin mismatches, and invalid credential events
Rollback guidance
Section titled “Rollback guidance”If an integrations rollout causes consumer regressions:
- stop promoting new consumer releases that depend on the changed behavior
- restore the prior API behavior if the regression is in this repo and backward compatibility was unintentionally broken
- if the API behavior is correct but the consumer is not, roll back the external consumer repository release
- keep or reissue the prior installation credential if needed during rollback
- confirm health, installation resolution, and the affected scoped endpoint behavior before resuming rollout
Rollback must preserve the published contract or clearly version any intentional breaking change before consumers upgrade.
Pull request expectations in this repo
Section titled “Pull request expectations in this repo”When changing the integrations surface in this monorepo:
- update
packages/api-contractfirst or in the same change - regenerate docs artifacts from the canonical contract
- run the integrations contract/runtime/resilience validation lanes
- document any downstream action required in external consumer repositories
- avoid merging undocumented runtime behavior that external consumers could discover accidentally
Repository split expectations
Section titled “Repository split expectations”Consumer repositories should avoid embedding undocumented assumptions about:
- dashboard-only routes
- internal D1 schema details
- Better Auth tables or metadata layouts
- non-versioned public API behavior outside
/integrations/v1
This monorepo remains the source of truth for integrations API behavior; consumer repositories remain replaceable clients.
WordPress recipe: list all people
Section titled “WordPress recipe: list all people”This section is for WordPress (or any other integrations consumer) that needs to list people using an installation credential.
Endpoint and auth:
- Method:
GET - URL:
https://api.legaciti.org/integrations/v1/people - Header:
X-API-Key: <installation-credential> - Required scope:
people.read
Optional query parameters:
page(default1, minimum1)per_page(default20, minimum1, maximum100)q(optional free-text filter on name/ORCID)
Example request:
curl -sS "https://api.legaciti.org/integrations/v1/people?page=1&per_page=100&q=" \ -H "X-API-Key: $INTEGRATION_API_KEY" \ -H "Accept: application/json"Expected 200 response shape:
{ "people": [ { "orcid_id": "0000-0002-1825-0097", "name": "Ada Lovelace", "biography": null, "last_fetched_at": 1762050000000, "sync_status": "complete", "publication_count": 12 }, { "orcid_id": "0000-0001-2345-6789", "name": { "en": "Joao Silva", "pt": "Joao Silva" }, "biography": { "en": "Researcher in marine ecology", "pt": "Investigador em ecologia marinha" }, "last_fetched_at": 1762040000000, "sync_status": "complete", "publication_count": 7 } ], "page": 1, "per_page": 100, "total": 2, "pages": 1, "q": ""}Common error responses to handle:
400invalid query parameters401missing or invalid credential403inactive credential, unverified origin, or missing scope429installation rate limit exceeded