> ## Documentation Index
> Fetch the complete documentation index at: https://docs-pos.solya.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit a company's fiscal identity (appends a version)

> Replaces the fiscal identity WHOLESALE — this is not a patch. Read the société first, apply your change to `current.identity`, and send the whole object; an omitted optional field is CLEARED. The edit APPENDS version N+1 with `effectiveFrom` = now and bumps the société's `currentVersion`; no stored version is ever mutated, so every sale finalized under an earlier version keeps printing that version's header. Submitting an UNCHANGED identity mints nothing and returns the current version (the fingerprint is a content address, so a no-op save cannot grow the chain). The body's `id` is required by validation but IGNORED — the path `companyId` wins. The country is NOT editable here: changing which fiscal regime an entity lives under is a new société. 404s for an unknown société; 400 with a field error on a check-unsound identifier.



## OpenAPI

````yaml /openapi.json put /v1/companies/{companyId}/identity
openapi: 3.0.3
info:
  title: Solya POS API
  version: 1.0.0
  description: >-
    The Solya POS backend HTTP surface. Every documented operation is
    agent-ready: it carries an `operationId`, an agent-facing `description`, the
    `pos.*` scopes it enforces (`x-required-permissions`) and an `x-agent-tier`.
    Success responses return the payload as raw JSON; failures return the
    `ErrorResponse` envelope (`{ error: { code, message, statusCode } }`).
servers:
  - url: /
    description: The backend, relative to its deployed origin.
security: []
paths:
  /v1/companies/{companyId}/identity:
    put:
      tags:
        - Network
      summary: Edit a company's fiscal identity (appends a version)
      description: >-
        Replaces the fiscal identity WHOLESALE — this is not a patch. Read the
        société first, apply your change to `current.identity`, and send the
        whole object; an omitted optional field is CLEARED. The edit APPENDS
        version N+1 with `effectiveFrom` = now and bumps the société's
        `currentVersion`; no stored version is ever mutated, so every sale
        finalized under an earlier version keeps printing that version's header.
        Submitting an UNCHANGED identity mints nothing and returns the current
        version (the fingerprint is a content address, so a no-op save cannot
        grow the chain). The body's `id` is required by validation but IGNORED —
        the path `companyId` wins. The country is NOT editable here: changing
        which fiscal regime an entity lives under is a new société. 404s for an
        unknown société; 400 with a field error on a check-unsound identifier.
      operationId: updateCompanyIdentity
      parameters:
        - schema:
            type: string
            minLength: 1
          in: path
          name: companyId
          required: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  minLength: 1
                identity:
                  type: object
                  properties:
                    legalName:
                      type: string
                      minLength: 1
                    legalForm:
                      type: string
                      minLength: 1
                    registrationNumber:
                      type: string
                      minLength: 1
                    vatNumber:
                      type: string
                      minLength: 1
                    shareCapitalCents:
                      type: integer
                      minimum: 0
                      maximum: 9007199254740991
                    registryLabel:
                      type: string
                      minLength: 1
                    address:
                      type: object
                      properties:
                        lines:
                          type: array
                          items:
                            type: string
                            minLength: 1
                        postalCode:
                          type: string
                          minLength: 1
                        city:
                          type: string
                          minLength: 1
                        country:
                          type: string
                          pattern: ^[A-Z]{2}$
                      required:
                        - lines
                        - country
                    phone:
                      type: string
                      minLength: 1
                    email:
                      type: string
                      minLength: 1
                    statutoryMentions:
                      type: array
                      items:
                        type: string
                        minLength: 1
                  required:
                    - legalName
                    - address
              required:
                - id
                - identity
              example:
                id: le-solya
                identity:
                  legalName: Solya Retail
                  legalForm: SAS
                  registrationNumber: '732829320'
                  vatNumber: FR44732829320
                  shareCapitalCents: 1000000
                  registryLabel: RCS Paris 732 829 320
                  address:
                    lines:
                      - 7 rue Neuve
                    postalCode: '75001'
                    city: Paris
                    country: FR
                  statutoryMentions:
                    - TVA non applicable, art. 293 B du CGI
      responses:
        '200':
          description: The société and the identity version now in force.
          content:
            application/json:
              schema:
                type: object
                properties:
                  entity:
                    type: object
                    properties:
                      id:
                        type: string
                        minLength: 1
                      country:
                        type: string
                        pattern: ^[A-Z]{2}$
                      currentVersion:
                        type: integer
                        minimum: 0
                        exclusiveMinimum: true
                        maximum: 9007199254740991
                    required:
                      - id
                      - country
                      - currentVersion
                    additionalProperties: false
                  current:
                    type: object
                    properties:
                      legalEntityId:
                        type: string
                        minLength: 1
                      version:
                        type: integer
                        minimum: 0
                        exclusiveMinimum: true
                        maximum: 9007199254740991
                      effectiveFrom:
                        type: string
                        minLength: 1
                      fingerprint:
                        type: string
                        minLength: 1
                      identity:
                        type: object
                        properties:
                          legalName:
                            type: string
                            minLength: 1
                          legalForm:
                            type: string
                            minLength: 1
                          registrationNumber:
                            type: string
                            minLength: 1
                          vatNumber:
                            type: string
                            minLength: 1
                          shareCapitalCents:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          registryLabel:
                            type: string
                            minLength: 1
                          address:
                            type: object
                            properties:
                              lines:
                                type: array
                                items:
                                  type: string
                                  minLength: 1
                              postalCode:
                                type: string
                                minLength: 1
                              city:
                                type: string
                                minLength: 1
                              country:
                                type: string
                                pattern: ^[A-Z]{2}$
                            required:
                              - lines
                              - country
                            additionalProperties: false
                          phone:
                            type: string
                            minLength: 1
                          email:
                            type: string
                            minLength: 1
                          statutoryMentions:
                            type: array
                            items:
                              type: string
                              minLength: 1
                        required:
                          - legalName
                          - address
                        additionalProperties: false
                    required:
                      - legalEntityId
                      - version
                      - effectiveFrom
                      - fingerprint
                      - identity
                    additionalProperties: false
                required:
                  - entity
                  - current
                additionalProperties: false
                description: The société and the identity version now in force.
                example:
                  entity:
                    id: le-solya
                    country: FR
                    currentVersion: 1
                  current:
                    legalEntityId: le-solya
                    version: 1
                    effectiveFrom: '2026-02-01T09:00:00.000Z'
                    fingerprint: >-
                      9f2c1a5b7e0d4c3f8a6b2e1d9c0f7a4b5e3d2c1f0a9b8c7d6e5f4a3b2c1d0e9f
                    identity:
                      legalName: Solya Retail
                      legalForm: SAS
                      registrationNumber: '732829320'
                      vatNumber: FR44732829320
                      shareCapitalCents: 1000000
                      registryLabel: RCS Paris 732 829 320
                      address:
                        lines:
                          - 12 rue de Rivoli
                        postalCode: '75001'
                        city: Paris
                        country: FR
                      statutoryMentions:
                        - TVA non applicable, art. 293 B du CGI
        '400':
          description: >-
            The request failed schema validation; `error.fieldErrors` lists the
            fields.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
        '401':
          description: No valid credential was presented — send a bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: The actor is authenticated but lacks the required `pos.*` scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: No resource matches the addressed identifier.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: An unexpected server error — safe to retry idempotent requests.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    ValidationErrorResponse:
      type: object
      required:
        - error
      additionalProperties: false
      description: >-
        A `VALIDATION_FAILED` envelope carrying the offending fields in
        `fieldErrors`.
      properties:
        error:
          type: object
          required:
            - code
            - message
            - statusCode
          additionalProperties: false
          properties:
            code:
              type: string
              enum:
                - VALIDATION_FAILED
            message:
              type: string
            statusCode:
              type: integer
            fieldErrors:
              type: array
              description: >-
                One entry per rejected field: the field path and why it was
                rejected.
              items:
                type: object
                required:
                  - field
                  - message
                additionalProperties: false
                properties:
                  field:
                    type: string
                    description: Dot-path of the offending field.
                  message:
                    type: string
                    description: Why the field was rejected.
    ErrorResponse:
      type: object
      required:
        - error
      additionalProperties: false
      description: The uniform failure envelope every non-2xx response returns.
      properties:
        error:
          type: object
          required:
            - code
            - message
            - statusCode
          additionalProperties: false
          properties:
            code:
              type: string
              enum:
                - VALIDATION_FAILED
                - UNAUTHORIZED
                - FORBIDDEN
                - NOT_FOUND
                - CONFLICT
                - BUSINESS_RULE_VIOLATION
                - INTERNAL_ERROR
              description: >-
                Machine-readable kernel `ResultCode` — branch on this, not on
                `message`.
            message:
              type: string
              description: >-
                Human-readable explanation. Safe to surface; never leaks server
                internals.
            statusCode:
              type: integer
              description: >-
                The HTTP status, mirrored into the body so a client need not
                read headers.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        `Authorization: Bearer <token>`. Accepts EITHER a Keycloak access token
        (scopes-in-token) OR an opaque POS session token; both resolve to the
        same `pos.*` scope vocabulary the route guards enforce.

````