openapi: 3.1.1 info: title: Arcadia Genesis API (for PHP client) version: 1.0.0 summary: Proposed HTTP API contract consumed by arcadia-genesis-php-client description: | This specification describes the API surface implied by the PHP client. It models employee and INCO sheet use cases exposed by the client services. servers: - url: https://api.example.com/gaston/api description: Example production server security: - ArcadiaAuth: [] tags: - name: Employees - name: IncoSheets - name: IncoComposition paths: /employees: get: tags: [Employees] operationId: listEmployees summary: List employees description: | Returns a paginated list of employees. Supports optional filtering by update timestamp and site ids. parameters: - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' - $ref: '#/components/parameters/Since' - $ref: '#/components/parameters/EmployeeSortBy' - $ref: '#/components/parameters/SortDirection' - name: siteIds in: query required: false description: Filter on one or many site ids style: form explode: true schema: type: array minItems: 1 items: type: string responses: '200': description: Employees page content: application/json: schema: $ref: '#/components/schemas/EmployeeListResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' /employees/{employeeId}: get: tags: [Employees] operationId: getEmployeeById summary: Get an employee by id parameters: - name: employeeId in: path required: true schema: type: string responses: '200': description: Employee detail content: application/json: schema: $ref: '#/components/schemas/EmployeeItemResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': description: Employee not found content: application/json: schema: $ref: '#/components/schemas/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' /inco-sheets: get: tags: [IncoSheets] operationId: listIncoSheets summary: List INCO sheets description: | Returns paginated INCO sheets. Supports brand filtering and optional updated_at lower bound. parameters: - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' - $ref: '#/components/parameters/Since' - $ref: '#/components/parameters/IncoSortBy' - $ref: '#/components/parameters/SortDirection' - name: brands in: query required: false description: Filter on one or many brand codes style: form explode: true schema: type: array minItems: 1 items: type: string responses: '200': description: INCO sheets page content: application/json: schema: $ref: '#/components/schemas/IncoListResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' /inco-sheets/short: get: tags: [IncoSheets] operationId: listIncoSheetsShort summary: List INCO sheets (short payload) parameters: - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PageSize' - $ref: '#/components/parameters/IncoSortBy' - $ref: '#/components/parameters/SortDirection' - name: brands in: query required: true description: One or many brand codes style: form explode: true schema: type: array minItems: 1 items: type: string responses: '200': description: INCO short page content: application/json: schema: $ref: '#/components/schemas/IncoShortListResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' /inco-sheets/search: get: tags: [IncoSheets] operationId: searchIncoSheetsByIdLike summary: Search INCO sheets by id-like pattern parameters: - name: incoIdLike in: query required: true schema: type: string description: Pattern used with SQL-like matching rules - name: brands in: query required: true style: form explode: true schema: type: array minItems: 1 items: type: string - name: short in: query required: false schema: type: boolean default: false description: Return short projection when true responses: '200': description: Search result (first page, size 50) content: application/json: schema: oneOf: - $ref: '#/components/schemas/IncoListResponse' - $ref: '#/components/schemas/IncoShortListResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' /inco-sheets/{incoId}: get: tags: [IncoSheets] operationId: getIncoSheetById summary: Get INCO sheet by id parameters: - name: incoId in: path required: true schema: type: string pattern: '^\\d{1,}$' responses: '200': description: INCO sheet detail content: application/json: schema: $ref: '#/components/schemas/IncoItemResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': description: INCO not found content: application/json: schema: $ref: '#/components/schemas/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' /inco-sheets/{incoId}/composition: get: tags: [IncoComposition] operationId: getIncoCompositionByIncoId summary: Get composition by INCO id parameters: - name: incoId in: path required: true schema: type: string pattern: '^\\d{1,}$' responses: '200': description: Composition detail content: application/json: schema: $ref: '#/components/schemas/IncoCompoItemResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': description: Composition not found content: application/json: schema: $ref: '#/components/schemas/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' /inco-compositions/{incoCompoId}: get: tags: [IncoComposition] operationId: getIncoCompositionById summary: Get composition by composition id parameters: - name: incoCompoId in: path required: true schema: type: string pattern: '^\\d{1,}$' responses: '200': description: Composition detail content: application/json: schema: $ref: '#/components/schemas/IncoCompoItemResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': description: Composition not found content: application/json: schema: $ref: '#/components/schemas/NotFoundResponse' '429': $ref: '#/components/responses/TooManyRequests' '503': $ref: '#/components/responses/ServiceUnavailable' components: securitySchemes: ArcadiaAuth: type: apiKey in: header name: X-API-Key description: | Requests also require `X-API-Signature` and `X-Timestamp` headers. Signature is computed from method, URI, body payload, shared secret, and timestamp. parameters: Page: name: page in: query required: false schema: type: integer minimum: 1 default: 1 description: 1-based page index PageSize: name: page_size in: query required: false schema: type: integer minimum: 1 default: 50 maximum: 10000 description: Max records per page Since: name: since in: query required: false schema: type: string format: date-time description: RFC3339 timestamp lower bound (>=) SortDirection: name: sortDirection in: query required: false schema: type: string enum: [asc, desc] default: desc EmployeeSortBy: name: sortBy in: query required: false schema: type: string enum: - arcadiaId - startDate - endDate - plannedEndDate - createdAt - updatedAt IncoSortBy: name: sortBy in: query required: false schema: type: string enum: - id - createdAt - updatedAt responses: BadRequest: description: Invalid request content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' Unauthorized: description: Authentication failed content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' TooManyRequests: description: Rate limited content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' ServiceUnavailable: description: Upstream service unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' schemas: Employee: type: object additionalProperties: false required: - matriculePublique - lastname - firstname - start_date - establishment - site - service - created_at properties: matriculePublique: type: string lastname: type: string firstname: type: string start_date: type: string format: date-time end_date: type: [string, 'null'] format: date-time planned_end_date: type: [string, 'null'] format: date-time establishment: type: string site: type: string service: type: string created_at: type: string format: date-time updated_at: type: [string, 'null'] format: date-time IncoBrand: type: object additionalProperties: false required: [code, label] properties: code: type: string label: type: string Inco: type: object additionalProperties: false required: - id - name - libelle - description - allegations - sellArguments - preparationAdvices - ingredients - allergens - brand - isSeasonal - additives properties: id: type: string pattern: '^\\d{1,}$' name: type: string libelle: type: string description: type: string allegations: type: object additionalProperties: true sellArguments: type: string preparationAdvices: type: string tips: type: [string, 'null'] sellFamilly: type: [string, 'null'] ingredients: type: object additionalProperties: true portions: type: [object, 'null'] additionalProperties: true allergens: type: array items: type: object additionalProperties: true brand: $ref: '#/components/schemas/IncoBrand' isSeasonal: type: boolean weight: type: [object, 'null'] additionalProperties: true nutriscore: type: [object, 'null'] additionalProperties: true storageCondition: type: [object, 'null'] additionalProperties: true additives: type: array items: type: object additionalProperties: true compo: type: [string, 'null'] pattern: '^\\d{1,}$' created_at: type: [string, 'null'] format: date-time updated_at: type: [string, 'null'] format: date-time IncoShort: type: object additionalProperties: false required: - id - name - libelle - description properties: id: type: string pattern: '^\\d{1,}$' name: type: string libelle: type: string description: type: string created_at: type: [string, 'null'] format: date-time updated_at: type: [string, 'null'] format: date-time IncoCompo: type: object additionalProperties: false required: - id - idInco - identification - energie - macronutrimentsRef - macronutrimentsPortion - fnl - apportsReference - nutriScore - pointsNutriScore - mineraux - vitamines - glucidesDetail - acideGras - acidesAmines - composesSpeciaux properties: id: type: string pattern: '^\\d{1,}$' idInco: type: string pattern: '^\\d{1,}$' identification: type: object additionalProperties: true energie: type: object additionalProperties: true macronutrimentsRef: type: object additionalProperties: true macronutrimentsPortion: type: object additionalProperties: true fnl: type: object additionalProperties: true apportsReference: type: object additionalProperties: true nutriScore: type: object additionalProperties: true pointsNutriScore: type: object additionalProperties: true mineraux: type: object additionalProperties: true vitamines: type: object additionalProperties: true glucidesDetail: type: object additionalProperties: true acideGras: type: object additionalProperties: true acidesAmines: type: object additionalProperties: true composesSpeciaux: type: object additionalProperties: true Pagination: type: object additionalProperties: false required: - page - pageSize - totalItems - totalPages - links properties: page: type: integer minimum: 1 pageSize: type: integer minimum: 1 totalItems: type: integer minimum: 0 totalPages: type: integer minimum: 0 links: type: object additionalProperties: false required: [first, last] properties: first: type: string format: uri last: type: string format: uri EmployeeListResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object properties: data: type: array items: $ref: '#/components/schemas/Employee' pagination: $ref: '#/components/schemas/Pagination' EmployeeItemResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object properties: data: $ref: '#/components/schemas/Employee' IncoListResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object properties: data: type: array items: $ref: '#/components/schemas/Inco' pagination: $ref: '#/components/schemas/Pagination' IncoShortListResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object properties: data: type: array items: $ref: '#/components/schemas/IncoShort' pagination: $ref: '#/components/schemas/Pagination' IncoItemResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object properties: data: $ref: '#/components/schemas/Inco' IncoCompoItemResponse: allOf: - $ref: '#/components/schemas/SuccessEnvelope' - type: object properties: data: $ref: '#/components/schemas/IncoCompo' SuccessEnvelope: type: object additionalProperties: false required: [success, data] properties: success: type: boolean const: true data: {} pagination: $ref: '#/components/schemas/Pagination' ApiErrorCode: type: string enum: - '0004' - ERR_UNAUTHORIZED_PARAMETER - ERR_DEFAULT - ERR_LIST_SIZE_MISMATCH - ERR_METAEXCEPTION - ERR_SORT_LIST_SIZE_MISMATCH - ERR_TABLE_NAME_MISSING - ERR_UNAUTHORIZED_OPERATOR - ERR_BAD_DATE_FORMAT - ERR_PAGE_TYPE_MISMATCH - ERR_PAGE_SIZE_TYPE_MISMATCH - ERR_TOO_MANY_RECORDS - ERR_INVALID_API_KEY - ERR_INVALID_API_SIGNATURE - ERR_TOO_MANY_REQUESTS - UNKNOWN ApiErrorObject: type: object additionalProperties: true required: [code] properties: code: $ref: '#/components/schemas/ApiErrorCode' message: type: string ApiErrorResponse: type: object additionalProperties: false required: [success, error] properties: success: type: boolean const: false error: oneOf: - $ref: '#/components/schemas/ApiErrorObject' - type: array items: $ref: '#/components/schemas/ApiErrorObject' NotFoundResponse: type: object additionalProperties: false required: [success, error] properties: success: type: boolean const: false error: type: object additionalProperties: false required: [code, message] properties: code: type: string enum: [NOT_FOUND] message: type: string