Customer aggregate API
The Management API exposes a customer-first profile and License summary for Vendor Console workflows. Tenant identity always comes from the authenticated session or service account; do not send a Tenant ID in the path, query, or body.
Read profile and Licenses
GET /api/v1/customers/organizations/{organizationId}/aggregate?licenseOffset=0&licenseLimit=50
Permission: customers.read
licenseOffset defaults to 0. licenseLimit defaults to 50 and accepts
1..200. Licenses are ordered newest-first with a stable License ID tie-break.
Archived, revoked, deprecated, and migration-required rows remain visible.
Each License reports Product resolution explicitly:
Resolvedincludes the same-Tenant catalog display name;MissingIdentitymeans the BC-LIC row has no Product ID;CatalogNotFoundmeans its Product ID is absent from the same Tenant catalog.
Keys are never revealed. maskedKey is present only with keyMaskStatus = Available; missing or incomplete legacy metadata returns null and an
explicit status.
Replace the mutable profile
PUT /api/v1/customers/organizations/{organizationId}/aggregate
Permission: customers.manage
Content-Type: application/json
{
"expectedRevision": 3,
"displayName": "Example Ltd",
"notes": "Operator notes",
"primaryContact": {
"contactId": null,
"displayName": "Jane Doe",
"email": "jane@example.test",
"phone": "+1 555 0100"
}
}
The successful response is the committed profile only. A different stale
revision returns customer_profile_revision_conflict; an exact lost-result
replay converges on the committed state. The server does not perform a
post-commit License or Product read.
Errors and safety
Stable errors include customer_aggregate_invalid_request,
customer_aggregate_not_found, customer_primary_contact_not_found,
customer_profile_revision_conflict, customer_profile_not_editable, and
customer_aggregate_dependency_unavailable. Wrong-Tenant resources are
indistinguishable from missing resources. Plaintext keys, hashes, provider
references, and internal License/Product codes are absent from this contract.