openapi: 3.1.0 info: title: WorkMesh External API version: 1.0.0 description: | Business-scoped customer API for governed extraction of WorkMesh Systems and records. Choose the canonical REST representation for applications, flat JSON for reporting tools, or CSV for straightforward tabular consumption. All representations use the same bearer authentication, scopes, System grants, Business capability, rate controls and usage ledger. servers: - url: https://api.workmesh.work/v1 description: Production API contract. Availability is enabled per WorkMesh Business and rollout state. - url: https://test.workmesh.work/v1 description: Test environment. Test credentials are issued separately and use the wmk_test_ prefix. security: - bearerAuth: [] tags: - name: Business - name: Systems - name: Records - name: Reporting - name: Synchronisation paths: /business: get: tags: [Business] summary: Get the connected Business operationId: getBusiness responses: '200': description: Connected Business identity content: application/json: schema: $ref: '#/components/schemas/BusinessResponse' '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } /systems: get: tags: [Systems] summary: List Systems granted to the Connection operationId: listSystems parameters: - $ref: '#/components/parameters/Archived' responses: '200': description: Granted Systems content: application/json: schema: type: object required: [data, meta] properties: data: type: array items: { $ref: '#/components/schemas/System' } meta: { $ref: '#/components/schemas/ListMeta' } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } /systems/{system_key}: get: tags: [Systems] summary: Get System metadata operationId: getSystem parameters: - $ref: '#/components/parameters/SystemKey' responses: '200': description: System metadata content: application/json: schema: type: object required: [data, meta] properties: data: { $ref: '#/components/schemas/System' } meta: { $ref: '#/components/schemas/RequestMeta' } '401': { $ref: '#/components/responses/Unauthorized' } '404': { $ref: '#/components/responses/NotFound' } /systems/{system_key}/schema: get: tags: [Systems] summary: Get the governed System Field dictionary operationId: getSystemSchema parameters: - $ref: '#/components/parameters/SystemKey' responses: '200': description: System schema and authorised Fields content: application/json: schema: type: object required: [data, meta] properties: data: type: object required: [system, fields] properties: system: { $ref: '#/components/schemas/System' } fields: type: array items: { $ref: '#/components/schemas/FieldDefinition' } meta: { $ref: '#/components/schemas/RequestMeta' } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '404': { $ref: '#/components/responses/NotFound' } /systems/{system_key}/records: get: tags: [Records] summary: List canonical REST records description: | Rich application-oriented JSON envelope. User-defined values are returned under `fields` using stable WorkMesh `field_key` names and logical typed values. Reference Fields remain logical references in this canonical application profile. operationId: listSystemRecords parameters: - $ref: '#/components/parameters/SystemKey' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Archived' responses: '200': description: Paged canonical records content: application/json: schema: type: object required: [data, meta] properties: data: type: array items: { $ref: '#/components/schemas/CanonicalRecord' } meta: { $ref: '#/components/schemas/RecordListMeta' } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '404': { $ref: '#/components/responses/NotFound' } '410': { $ref: '#/components/responses/CursorGone' } '429': { $ref: '#/components/responses/RateLimited' } /systems/{system_key}/records/flat: get: tags: [Reporting] summary: List reporting-friendly flat JSON records description: | Recommended for Power BI, Tableau, Qlik and other analytics clients that work best with rows and columns. The response body is a root JSON array. Authorised WorkMesh Fields are promoted to top-level properties using stable `field_key` names. Record metadata uses reserved underscore-prefixed properties. Choice and person values may include companion `__key`, `__keys` or `__id` properties. Reference Fields are denormalised into the row: each authorised Reference Field exposes the selected Reference Table business values as `__` columns instead of requiring a downstream Reference join. Heatmap References expose their selected horizontal axis, vertical axis and cell values in the same form. Physical Reference Table names and raw Reference row identifiers are not exposed. operationId: listSystemRecordsFlat parameters: - $ref: '#/components/parameters/SystemKey' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Archived' responses: '200': description: Flat JSON rows headers: X-WorkMesh-Record-Count: { $ref: '#/components/headers/RecordCount' } X-WorkMesh-Next-Cursor: { $ref: '#/components/headers/NextCursor' } X-WorkMesh-High-Water-Cursor: { $ref: '#/components/headers/HighWaterCursor' } X-WorkMesh-Schema-Revision: { $ref: '#/components/headers/SchemaRevision' } X-WorkMesh-Truncated: { $ref: '#/components/headers/Truncated' } content: application/json: schema: type: array items: { $ref: '#/components/schemas/FlatRecord' } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '404': { $ref: '#/components/responses/NotFound' } '410': { $ref: '#/components/responses/CursorGone' } '429': { $ref: '#/components/responses/RateLimited' } /systems/{system_key}/records.csv: get: tags: [Reporting] summary: List reporting-friendly CSV records description: | Direct tabular representation for Excel, Power BI, Tableau, Qlik and other CSV consumers. Column names follow the same stable flat projection as `/records/flat`, including the denormalised `__` columns for authorised Reference Fields. operationId: listSystemRecordsCsv parameters: - $ref: '#/components/parameters/SystemKey' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Cursor' - $ref: '#/components/parameters/Archived' responses: '200': description: CSV rows headers: X-WorkMesh-Record-Count: { $ref: '#/components/headers/RecordCount' } X-WorkMesh-Next-Cursor: { $ref: '#/components/headers/NextCursor' } X-WorkMesh-High-Water-Cursor: { $ref: '#/components/headers/HighWaterCursor' } X-WorkMesh-Schema-Revision: { $ref: '#/components/headers/SchemaRevision' } X-WorkMesh-Truncated: { $ref: '#/components/headers/Truncated' } content: text/csv: schema: type: string '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '404': { $ref: '#/components/responses/NotFound' } '410': { $ref: '#/components/responses/CursorGone' } '429': { $ref: '#/components/responses/RateLimited' } /systems/{system_key}/records/{record_id}: get: tags: [Records] summary: Get one canonical record operationId: getSystemRecord parameters: - $ref: '#/components/parameters/SystemKey' - name: record_id in: path required: true schema: { type: string, format: uuid } responses: '200': description: Canonical record content: application/json: schema: type: object required: [data, meta] properties: data: { $ref: '#/components/schemas/CanonicalRecord' } meta: { $ref: '#/components/schemas/RequestMeta' } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '404': { $ref: '#/components/responses/NotFound' } /systems/{system_key}/changes: get: tags: [Synchronisation] summary: Get incremental material changes operationId: listSystemChanges parameters: - $ref: '#/components/parameters/SystemKey' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Cursor' responses: '200': description: Change feed or initial high-water cursor content: application/json: schema: type: object required: [data, meta] properties: data: type: array items: type: object additionalProperties: true meta: { $ref: '#/components/schemas/RecordListMeta' } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '404': { $ref: '#/components/responses/NotFound' } '410': { $ref: '#/components/responses/CursorGone' } /systems/{system_key}/records/{record_id}/history: get: tags: [Records] summary: Get governed immutable record History operationId: getSystemRecordHistory parameters: - $ref: '#/components/parameters/SystemKey' - name: record_id in: path required: true schema: { type: string, format: uuid } - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Cursor' responses: '200': description: Record History content: application/json: schema: type: object required: [data, meta] properties: data: type: array items: type: object additionalProperties: true meta: { $ref: '#/components/schemas/RecordListMeta' } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '404': { $ref: '#/components/responses/NotFound' } components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: WorkMesh API credential description: Use the bearer credential issued to the External API Connection for this environment. parameters: SystemKey: name: system_key in: path required: true schema: type: string pattern: '^[a-z][a-z0-9_]{0,79}$' Limit: name: limit in: query required: false schema: type: integer minimum: 1 maximum: 1000 default: 500 Cursor: name: cursor in: query required: false schema: { type: string } description: Opaque cursor supplied by WorkMesh. Clients must not construct or interpret it. Archived: name: archived in: query required: false schema: { type: boolean, default: false } description: False returns current records/Systems. True returns archived records/Systems where supported. headers: RecordCount: description: Number of rows returned in this response. schema: { type: integer } NextCursor: description: Opaque cursor for the next page. Omitted on the final page. schema: { type: string } HighWaterCursor: description: Opaque high-water cursor for incremental synchronisation. schema: { type: string } SchemaRevision: description: Current logical schema revision for the System. schema: { type: string } Truncated: description: True when the normal response-size guard ended the page before the requested limit. schema: { type: boolean } schemas: BusinessResponse: type: object required: [data, meta] properties: data: type: object required: [business_id, name] properties: business_id: { type: string, format: uuid } name: { type: string } code: { type: [string, 'null'] } meta: { $ref: '#/components/schemas/RequestMeta' } System: type: object required: [system_id, system_key, name, status, schema_revision] properties: system_id: { type: string } system_key: { type: string } name: { type: string } description: { type: [string, 'null'] } status: { type: string, enum: [current, archived] } schema_revision: { type: string } FieldDefinition: type: object required: [field_id, field_key, label, type] properties: field_id: { type: string } field_key: { type: string } qualified_key: { type: string } flat_export_key: { type: string } label: { type: string } type: { type: string } required: { type: boolean } read_only: { type: boolean } calculated: { type: boolean } writable: { type: boolean } CanonicalRecord: type: object required: [record_id, system_key, schema_revision, archived, is_final, revision, fields] properties: record_id: { type: string, format: uuid } system_key: { type: string } schema_revision: { type: string } state: oneOf: - type: 'null' - type: object properties: key: { type: string } label: { type: string } is_terminal: { type: boolean } archived: { type: boolean } is_final: { type: boolean } created_at: { type: [string, 'null'] } updated_at: { type: [string, 'null'] } revision: { type: string } fields: type: object additionalProperties: true FlatRecord: type: object description: >- Reporting row. Authorised WorkMesh Fields are top-level properties keyed by stable field_key. Authorised Reference Fields are denormalised into prefixed business-value columns rather than exposing a raw Reference row identity. required: [_record_id, _system_key, _schema_revision, _archived, _is_final] properties: _record_id: { type: string, format: uuid } _system_key: { type: string } _schema_revision: { type: string } _state: { type: [string, 'null'] } _state_key: { type: [string, 'null'] } _archived: { type: boolean } _is_final: { type: boolean } _created_at: { type: [string, 'null'] } _updated_at: { type: [string, 'null'] } _revision: { type: string } additionalProperties: true RequestMeta: type: object required: [request_id] properties: request_id: { type: string } ListMeta: allOf: - $ref: '#/components/schemas/RequestMeta' - type: object properties: count: { type: integer } requested_limit: { type: integer } next_cursor: { type: [string, 'null'] } truncated_by_response_size: { type: boolean } RecordListMeta: allOf: - $ref: '#/components/schemas/ListMeta' - type: object properties: high_water_cursor: { type: [string, 'null'] } ErrorResponse: type: object required: [error, meta] properties: error: type: object required: [code, message] properties: code: { type: string } message: { type: string } details: true meta: { $ref: '#/components/schemas/RequestMeta' } responses: Unauthorized: description: Missing, invalid, expired, revoked or wrong-environment credential. content: application/json: schema: { $ref: '#/components/schemas/ErrorResponse' } Forbidden: description: The Business capability or required Connection scope does not permit the operation. content: application/json: schema: { $ref: '#/components/schemas/ErrorResponse' } NotFound: description: The resource does not exist or is not available to this Connection. content: application/json: schema: { $ref: '#/components/schemas/ErrorResponse' } CursorGone: description: The supplied cursor expired or was invalidated by a continuity-breaking restore. content: application/json: schema: { $ref: '#/components/schemas/ErrorResponse' } RateLimited: description: Credential or Business rate/concurrency protection limit reached. headers: Retry-After: schema: { type: integer } content: application/json: schema: { $ref: '#/components/schemas/ErrorResponse' }