generated: '2026-09-02' method: derived source: graphql/venn-tenant.graphql note: >- Derived from the live GraphQL schema at https://api.venn.city/production/graphql (introspected anonymously, 2026-09-02) plus observed gateway responses. Venn publishes no conventions or API-design guide, so every statement below is either read out of the contract or observed on the wire, and each carries its evidence. api: name: Venn Tenant GraphQL API style: GraphQL (Apollo Federation gateway over per-domain subgraphs) endpoint: https://api.venn.city/production/graphql transport: HTTPS POST, application/json schema_generation: >- OpenCRUD-shaped, generated by Venn's own `@venncity/opencrud-schema-provider` over a Prisma/Sequelize data layer — which is why every entity carries a uniform ``, `s`, `sConnection` read triple and `create/update/updateMany/delete/deleteMany` mutations. authentication: style: bearer JWT (AWS Cognito), with a modelled per-user API key as a secondary credential header: Authorization detail: ../authentication/venn-authentication.yml pagination: style: relay-cursor enforced: true enforcement_error: pagination_enforce_error enforcement_evidence: >- An unpaginated list query returns `{"errors":[{"message":"Cant fetch all data - must send query with first or last arguments","extensions":{"code":"pagination_enforce_error","serviceName":"persistency"}}]}`. The enforcement is implemented by Venn's own published library `@venncity/graphql-pagination-enforce`. arguments: - name: first used_by_query_fields: 201 - name: last used_by_query_fields: 192 - name: after used_by_query_fields: 192 - name: before used_by_query_fields: 192 - name: skip used_by_query_fields: 200 - name: orderBy used_by_query_fields: 194 - name: where used_by_query_fields: 303 connection_shape: type_suffix: Connection fields: [aggregate, edges, pageInfo] page_info: [startCursor, endCursor, hasNextPage, hasPreviousPage] aggregate: >- Every `Connection` carries an `aggregate` field, so a total count is available on the same round trip as a page. filtering: style: OpenCRUD where-input detail: >- Each list field takes a `WhereInput` supporting per-field operators (`_not`, `_in`, `_not_in`, `_lt`, `_lte`, `_gt`, `_gte`, `_contains`, `_not_contains`, `_starts_with`, `_ends_with`) plus `AND`/`OR`/`NOT` composition. sorting: style: enum detail: '`OrderByInput` enums with `_ASC` / `_DESC` members.' field_selection: style: native GraphQL selection sets — no sparse-fieldset or expansion parameter needed. request_tracing: supported: true request_header: venn-request-id response_header: venn-request-id evidence: >- `venn-request-id` appears both in the gateway's Access-Control-Allow-Headers (so a client may supply one) and as a response header on every observed call. Errors additionally carry `extensions.traceId`. client_awareness_headers: - apollographql-client-name - apollographql-client-version error_envelope: style: graphql-errors rfc9457: false shape: errors: - message: human-readable locations: '[{line, column}]' path: '[field path]' extensions: code: machine-readable error code serviceName: originating subgraph (e.g. persistency) traceId: uuid logLevel: warn | error query: the failing query text variables: the failing variables exception: stacktrace: 'server stack trace — see security note' http_status_on_error: 200 detail: ../errors/venn-error-codes.yml security_note: >- The gateway returns a full server-side `exception.stacktrace`, including internal webpack paths and `@apollo/gateway` internals, to unauthenticated callers. This is a hardening gap worth reporting to Venn, not a feature. idempotency: support: partial api_wide_header: null detail: >- There is no API-wide idempotency key header or argument. `idempotencyKey` (String) exists on exactly one entity — `Notification` — and on `SendNotificationToUserParams`, so notification sends can be de-duplicated and nothing else can. A retried `createPaymentTransaction`, `createBill` or `createServiceProductOrder` has no published de-duplication guarantee. scoped_to: - Notification.idempotencyKey - NotificationCreateInput.idempotencyKey - NotificationUpdateInput.idempotencyKey - SendNotificationToUserParams.idempotencyKey pointer_note: >- Deliberately NOT wired as a `type: Idempotency` pointer in apis.yml. The support is real but covers one entity out of 468, so claiming it would credit Venn with an API-wide retry-safety property the contract does not provide. dry_run_mode: supported: false evidence: No dry-run, preview, simulate or validate-only argument appears anywhere in the schema. reversibility: grade: documented grade_basis: >- Reversal operations exist and are named in the contract, but Venn publishes no documentation stating a window for any of them, so this cannot be graded `verified`. No window below is asserted, because no public source states one. write_surface: true operations: - action: cancelBooking reverses: bookTimeSlots / createCalendarBooking window: null window_source: null - action: cancelSubscriptionContract reverses: createSubscriptionContract window: null window_source: null - action: requestSubscriptionContractCancellation reverses: createSubscriptionContract note: request-shaped cancellation, implying an operator approval step window: null - action: cancelServiceProductOrderByBackOffice reverses: createServiceProductOrder note: back-office only — the resident-facing path is requestCancelationServiceProductOrder window: null - action: requestCancelationServiceProductOrder reverses: createServiceProductOrder window: null - action: 'delete / deleteMany' reverses: 'create' note: >- Soft delete. Every entity carries `deleted` and `deletedAt` fields and they are filterable and sortable, so a delete is recoverable in principle. No public restore mutation and no retention window is documented. window: null refund_operation: null refund_note: >- The schema models payments (PaymentTransaction, PaymentRequest, Invoice, Bill, PayoutPlan, calculateTransactionFee, calculateTransferFee) but exposes no refund, void or reverse mutation. Whether refunds happen through the upstream payment provider rather than the Venn API could not be established publicly. versioning: scheme: >- None at the contract level. The endpoint carries an AWS API Gateway stage name (`/production/`), not an API version, and the schema is unversioned — GraphQL field deprecation is the change mechanism. deprecation_directive: '@deprecated is available; see lifecycle/venn-lifecycle.yml for the count in use' platform_versioning: 'semver, published per release in the release notes (backend v2.4.x, frontend v3.25.x)' detail: ../lifecycle/venn-lifecycle.yml rate_limit_signaling: headers_observed: [] detail: ../rate-limits/venn-rate-limits.yml soft_delete: supported: true fields: [deleted, deletedAt] detail: Present on every entity in the schema and exposed in both where-inputs and order-by enums. audit: supported: true detail: >- A first-class `Audit` entity with `audit`/`audits`/`auditsConnection` queries, carrying `vennRequestId`, `graphqlQuery` and `graphqlVariables` fields — so the platform records API calls as auditable rows. cross_links: errors: ../errors/venn-error-codes.yml lifecycle: ../lifecycle/venn-lifecycle.yml authentication: ../authentication/venn-authentication.yml scopes: ../scopes/venn-scopes.yml rate_limits: ../rate-limits/venn-rate-limits.yml data_model: ../data-model/venn-data-model.yml x-evidence: checked: '2026-09-02' evidence: - url: https://api.venn.city/production/graphql status: 200