Skip to content

Changelog ​

Set-once contact email ​

  • PATCH /v1/club/contacts/{id} accepts an optional email, settable once on a contact that has none; once present it cannot be changed or cleared. Previously the route accepted no email at all.
  • Sending the address the contact already has is accepted as a no-op, so a read-modify-write client can echo it back.
  • A different address on a contact that already has one answers 400 invalid_request with details: [{ field: "email", code: "already set" }]; an address another person on the platform already uses answers the same with code: "already in use"; an explicit null is malformed.
  • POST /v1/club/contacts now answers a duplicate email with 400 invalid_request naming the field instead of 500 internal_error: already in this club for the main email, and householdMembers[i].draft.email for a household draft, with duplicate in request when the call repeats an address.
  • PATCH /v1/federation/people/{contactId} is unchanged: a federation registration requires an email, which cannot be corrected afterwards.

API reference request samples ​

  • Request samples now show the signing headers honestly: X-Sx-Key-Id is the one security scheme, and X-Sx-Timestamp, X-Sx-Nonce and X-Sx-Signature are required header parameters on every operation, with descriptions and examples. Previously all four headers showed the same placeholder secret.
  • OpenAPI gains servers (partner-api.sportsx.ai and partner-dev-api.sportsx.fun); write operations carry an Idempotency-Key example and contact create/update fields carry examples.
  • Documentation and contract-check changes only; API behaviour is unchanged.

Club OWNER-only scope grants ​

  • Replaced the P0 “unsupported for every issuer” decision for club.compliance.read_files, club.safety.read_sensitive, club.coaches.read, club.coaches.write, and club.federations.read with an exact-current-club OWNER-only grant rule.
  • Kept permission wildcard and role evidence separate: ADMIN, custom wildcard holders and owners of other clubs cannot grant these scopes.
  • Applied one server-owned grant ceiling to the scope catalog, credential creation and scope update. Existing keys retain explicit scopes only; strict reduction remains available and rotation does not expand them.

P5 contract publication ​

  • Published signed-only authentication; removed obsolete Bearer and runtime mock-demo guidance.
  • Frozen the current inventory at 96 explicit controller operations: public GET /health plus 95 signed /v1 operations on 85 path templates.
  • Added equal-route bilingual OpenAPI, source-ledger drift checks, missing-translation and missing-spec failures, and bilingual docs build gates.
  • Documented workspace Redis limits, fail-closed idempotency, five signing webhook events, canonical reconciliation and current provisioning/worker limitations.

P6 standalone Partner worker ​

  • Added explicit PARTNER_ROLE=api|worker startup with backward-compatible api default and fail-fast unknown roles.
  • Moved webhook queue consumption and recovery out of every Academy mode into the health-only worker; retained the shared producer in Partner API and Academy.
  • Added independent API/worker Kubernetes Deployments from the same bundle. Only the API has a Service/public route.
  • Added isolated Postgres/Redis runtime checks for role routes, queue registry identity, consumer ownership and shutdown.