openapi: 3.1.0 info: title: Greenhouse Audit Log API description: | The Audit Log API exposes a record of important events that occurred in Greenhouse during the prior 30 days, including who performed each event, the event target, and supporting request metadata. Authentication uses a short-lived JWT obtained from POST https://harvest.greenhouse.io/auth/jwt_access_token using a Harvest API key. Rate limits: 50 requests / 10s on standard reads, 3 requests / 30s on paginated reads. version: "1.0.0" contact: name: Greenhouse Software url: https://www.greenhouse.com email: developers@greenhouse.io servers: - url: https://auditlog.us.greenhouse.io description: US Production - url: https://harvest.greenhouse.io/auth description: JWT token issuer (Harvest) security: - BearerAuth: [] tags: - name: Auth description: JWT access token issuance. - name: Events description: Audit log events. paths: /jwt_access_token: post: tags: [Auth] summary: Issue Audit Log Access Token description: Exchanges a Harvest API key (HTTP Basic) for a JWT bearer token valid for 24 hours. operationId: issueAuditAccessToken servers: - url: https://harvest.greenhouse.io/auth security: - HarvestBasic: [] responses: '200': description: Token issued. content: application/json: schema: type: object properties: access_token: { type: string } token_type: { type: string, example: Bearer } expires_in: { type: integer, description: Seconds until expiration. } /events: get: tags: [Events] summary: List Audit Events description: Returns audit events filtered by performer, target, event type, request, and time range. operationId: listAuditEvents parameters: - name: before_time in: query schema: { type: string, format: date-time } - name: after_time in: query schema: { type: string, format: date-time } - name: date in: query schema: { type: string, format: date } - name: magic_time in: query description: Relative time keyword (e.g. last_24_hours, last_7_days). schema: { type: string } - name: performer_ids in: query schema: type: array items: { type: integer } style: form explode: false - name: performer_types in: query schema: type: array items: { type: string, enum: [User, ApiKey, System] } style: form explode: false - name: performer_ip_addresses in: query schema: type: array items: { type: string } style: form explode: false - name: event_types in: query schema: type: array items: { type: string } style: form explode: false - name: event_target_ids in: query schema: type: array items: { type: integer } style: form explode: false - name: event_target_types in: query schema: type: array items: { type: string } style: form explode: false - name: request_ids in: query schema: type: array items: { type: string } style: form explode: false - name: request_types in: query schema: type: array items: { type: string, enum: [API, UI, JobBoard, Webhook] } style: form explode: false - name: paging in: query description: Opaque pagination cursor returned by a previous response. schema: { type: string } responses: '200': description: Audit events. content: application/json: schema: type: object properties: events: type: array items: { $ref: '#/components/schemas/AuditEvent' } paging: type: object properties: next: { type: string, nullable: true } '429': description: Rate limit exceeded. components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT HarvestBasic: type: http scheme: basic schemas: AuditEvent: type: object properties: id: { type: string } event_type: { type: string } occurred_at: { type: string, format: date-time } performer: type: object properties: id: { type: integer } type: { type: string } ip_address: { type: string } email: { type: string, format: email, nullable: true } event_target: type: object properties: id: { type: integer } type: { type: string } request: type: object properties: id: { type: string } type: { type: string } method: { type: string } path: { type: string } user_agent: { type: string } changes: type: array items: type: object properties: field: { type: string } old_value: {} new_value: {}