openapi: 3.1.0 info: title: VetTime Public API version: "1.0.0" summary: Shift export for third-party systems description: > Exposes a tenant's current published shift assignments over a calendar-date range. Draft plans, internal employee IDs, absences, contracts, payroll and time-tracking data are not exposed. contact: name: VetTime Integrations url: https://vettime.de/entwickler/kontakt email: info@mymedtime.de servers: - url: https://app.vettime.de/api/public/v1 description: Production security: - bearerAuth: [] tags: - name: Shifts description: Published shift assignments paths: /shifts: get: tags: [Shifts] operationId: listShifts summary: List published shift assignments description: > Returns assignments that overlap the requested inclusive range from the latest published plan for each location and planning period. Maximum range is 366 calendar days. Dates use Europe/Berlin. parameters: - name: from in: query required: true description: First local date, inclusive. schema: type: string format: date - name: to in: query required: true description: Last local date, inclusive; not before `from`. schema: type: string format: date - name: location_id in: query required: false description: Restricts results to one tenant location. schema: type: integer minimum: 1 - name: limit in: query required: false description: Page size. schema: type: integer minimum: 1 maximum: 250 default: 100 - name: cursor in: query required: false description: Opaque `meta.next_cursor` from the preceding page. schema: type: string responses: "200": description: A page of shift assignments. headers: X-Request-Id: description: Correlation id for support requests. schema: type: string content: application/json: schema: $ref: "#/components/schemas/ShiftListResponse" "400": description: Invalid date, range, limit, location or cursor. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": description: Missing, malformed, revoked key or inactive tenant. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "429": description: Request limit exceeded; honor Retry-After. headers: Retry-After: schema: type: integer content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Transient server failure; retry with backoff and jitter. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" components: securitySchemes: bearerAuth: type: http scheme: bearer description: Tenant-scoped API key, e.g. `vt_live_...`. schemas: ShiftListResponse: type: object required: [data, meta] properties: data: type: array items: $ref: "#/components/schemas/ShiftAssignment" meta: $ref: "#/components/schemas/Meta" ShiftAssignment: type: object required: [id, local_date, starts_at, ends_at, timezone, employee, shift_type] properties: id: type: string format: uuid local_date: type: string format: date starts_at: type: string format: date-time ends_at: type: string format: date-time timezone: type: string examples: ["Europe/Berlin"] employee: $ref: "#/components/schemas/Employee" shift_type: $ref: "#/components/schemas/ShiftType" location: oneOf: - $ref: "#/components/schemas/Location" - type: "null" publication: oneOf: - $ref: "#/components/schemas/Publication" - type: "null" updated_at: type: [string, "null"] format: date-time Employee: type: object properties: external_id: type: [string, "null"] description: > Opaque, case-sensitive identifier configured by the tenant. Null when no mapping exists. Internal VetTime IDs are never returned and consumers must not match by name. first_name: type: string last_name: type: string display_name: type: string active: type: boolean role: oneOf: - $ref: "#/components/schemas/Role" - type: "null" skills: type: array items: $ref: "#/components/schemas/Skill" Role: type: object properties: id: type: string format: uuid name: type: string Skill: type: object properties: id: type: string format: uuid name: type: string source: type: string ShiftType: type: object properties: id: type: string format: uuid name: type: string color: type: string required_skills: type: array items: $ref: "#/components/schemas/Skill" Location: type: object properties: id: type: integer name: type: string slug: type: string Publication: type: object properties: schedule_id: type: string format: uuid published_at: type: [string, "null"] format: date-time Meta: type: object properties: tenant: type: object properties: id: type: integer name: type: string from: type: string format: date to: type: string format: date timezone: type: string limit: type: integer has_more: type: boolean next_cursor: type: [string, "null"] generated_at: type: string format: date-time ErrorResponse: type: object required: [error] properties: error: type: object required: [code, message] properties: code: type: string enum: - invalid_request - invalid_api_key - rate_limit_exceeded - internal_error message: type: string details: type: object additionalProperties: true