> ## Documentation Index
> Fetch the complete documentation index at: https://developer.worldly.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Publish French Eco-Scores

Submit finalized French Eco-Scores for products in your library to the French government's Affichage Environnemental portal.

<Note title="productIds">
  Specify an array of up to 50 product IDs to publish in a single request. IDs must be non-empty, unique, and non-blank.
</Note>

### Request body properties

| Name         | Type            | Description                                                                                                         |
| :----------- | :-------------- | :------------------------------------------------------------------------------------------------------------------ |
| `productIds` | `Array<string>` | **\[REQUIRED]** IDs of the products to publish. Must be non-empty, unique, and non-blank. Up to 50 IDs per request. |

### Implementation details

* **Batch limit**: You can publish a maximum of 50 products per request.
* **Eligibility re-check**: For each product, the server re-checks eligibility (GTIN, materials, manufacturing country, and other requirements) and enforces the 3-month re-publish lock before any portal call.
* **Status codes**: The endpoint returns `200` when every attempted product succeeded, `207` when at least one succeeded and at least one failed, and `400` when every attempted product failed.
* **Result handling**: Always inspect `failed[]` and `skipped[]` to confirm each product was filed — a `200` does not guarantee every product in the request was published.

### Response body properties

| Name        | Type            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| :---------- | :-------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `succeeded` | `Array<object>` | **\[REQUIRED]** Products accepted by the portal. `httpStatus` is `201` for a new declaration or `208` when the portal confirms an existing declaration is already on file. `publishedAt` and `nextEligibleAt` are populated only on `201`; on `208` the previously stored values remain. Products submitted in the same batch share `internalReference`.                                                                                                                                                              |
| `failed`    | `Array<object>` | **\[REQUIRED]** Products the portal rejected or that could not be persisted. `error` is a human-readable explanation; `httpStatus` (when present) is the upstream portal status code. Products in the same failed batch carry the same `error` and `httpStatus`.                                                                                                                                                                                                                                                      |
| `skipped`   | `Array<object>` | **\[REQUIRED]** Products the publish request did not attempt to submit to the portal. Reasons include ownership, the 3-month re-publish lock, a structural eligibility failure, or a concurrent Eco-Score change detected just before submission. `nextEligibleAt` is set when a reason is `WithinThreeMonthLock`; it is the Unix-ms timestamp at which the lock expires. `driftedPeer` is set when a reason is `GroupAbortedDueToPeerDrift`; it is the productId of the peer whose change caused the batch rollback. |

### Related recipes

<Card title="PIC - Update Product with French Eco-Score requirements" href="/recipes/french-eco-score-update" />

<Card title="PIC - Retrieve French Eco-Score" href="/recipes/retrieve-french-eco-score" />

Refer to the [PIC Data Dictionary](/data-dictionary/pic) for more information on French Eco-Score attributes.


## OpenAPI

````yaml api-reference/openapi/french-eco.json POST /french-label/publish
openapi: 3.0.0
info:
  title: pic-api
  version: 1.0.0
servers:
  - url: https://api-v2.production.higg.org/pic-api/v1
    description: Production
  - url: https://api-v2.demo.higg.org/pic-api/v1
    description: Demo
security:
  - sec0: []
    sec1: []
paths:
  /french-label/publish:
    post:
      summary: Publish French Eco-Scores to the Affichage Environnemental portal
      operationId: frenchLabelPublish
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FrenchLabelPublishRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrenchLabelPublishResponse'
        '207':
          description: Partial success — some products published, some failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrenchLabelPublishResponse'
        '400':
          description: All products failed to publish
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrenchLabelPublishResponse'
components:
  schemas:
    FrenchLabelPublishRequest:
      description: >-
        Request body for the French Eco-Score batch publish endpoint. Up to 50
        products per request.
      properties:
        productIds:
          items:
            type: string
          type: array
          description: >-
            IDs of the products to publish. Must be non-empty, unique, and
            non-blank. Up to 50 IDs per request.
      required:
        - productIds
      type: object
      additionalProperties: false
    FrenchLabelPublishResponse:
      description: >-
        Aggregate result of a French Eco-Score batch publish request. -
        `succeeded[]` — products accepted by the portal. - `failed[]` — products
        the portal rejected or that could not be persisted. - `skipped[]` —
        products the publish did not attempt (ownership, lock window,
        eligibility failure, or concurrent score change). Returned with HTTP 200
        when every attempted product succeeded, 207 when at least one succeeded
        and at least one failed, or 400 when every attempted product failed —
        callers MUST inspect `failed[]` and `skipped[]` to confirm individual
        products were filed.
      properties:
        succeeded:
          items:
            $ref: '#/components/schemas/FrenchLabelPublishSucceeded'
          type: array
        failed:
          items:
            $ref: '#/components/schemas/FrenchLabelPublishFailed'
          type: array
        skipped:
          items:
            $ref: '#/components/schemas/FrenchLabelPublishSkipped'
          type: array
      required:
        - failed
        - skipped
        - succeeded
      type: object
      additionalProperties: false
    FrenchLabelPublishSucceeded:
      description: >-
        Per-product outcome for products the Affichage Environnemental portal
        accepted. `httpStatus` is 201 for a new declaration or 208 when the
        portal confirms an existing declaration is already on file.
        `publishedAt` and `nextEligibleAt` are populated only on 201; on 208 the
        previously stored values remain. Products submitted in the same batch
        share `internalReference`.
      properties:
        productId:
          type: string
        httpStatus:
          type: string
          enum:
            - '201'
            - '208'
        internalReference:
          type: string
        publishedAt:
          type: number
          format: double
          nullable: true
        nextEligibleAt:
          type: number
          format: double
          nullable: true
      required:
        - httpStatus
        - internalReference
        - productId
      type: object
      additionalProperties: false
    FrenchLabelPublishFailed:
      description: >-
        Per-product outcome for products the portal rejected or that could not
        be persisted. `error` is a human-readable explanation; `httpStatus`
        (when present) is the upstream portal status code. Products in the same
        failed batch carry the same `error` and `httpStatus`.
      properties:
        productId:
          type: string
        httpStatus:
          type: number
          format: double
          nullable: true
        error:
          type: string
        code:
          type: string
          nullable: true
      required:
        - error
        - productId
      type: object
      additionalProperties: false
    FrenchLabelPublishSkipped:
      description: >-
        Per-product outcome for products the publish request did NOT attempt to
        submit to the portal. Reasons include ownership, the 3-month re-publish
        lock, a structural eligibility failure, or a concurrent Eco-Score change
        detected just before submission. - `nextEligibleAt` is set when a reason
        is `WithinThreeMonthLock`; it is the Unix-ms timestamp at which the lock
        expires. - `driftedPeer` is set when a reason is
        `GroupAbortedDueToPeerDrift`; it is the productId of the peer whose
        change caused the batch rollback.
      properties:
        productId:
          type: string
        reasons:
          items:
            $ref: '#/components/schemas/FrenchLabelPublishSkipReason'
          type: array
        nextEligibleAt:
          type: number
          format: double
          nullable: true
        driftedPeer:
          type: string
          nullable: true
      required:
        - productId
        - reasons
      type: object
      additionalProperties: false
    FrenchLabelPublishSkipReason:
      description: >-
        Reason a product was skipped during a publish request. Use `code` for
        programmatic handling and `message` for human-readable display.
      properties:
        code:
          $ref: '#/components/schemas/FrenchLabelPublishSkipCode'
        message:
          type: string
          description: Human-readable explanation of why the product was skipped.
      required:
        - code
        - message
      type: object
      additionalProperties: false
    FrenchLabelPublishSkipCode:
      description: >-
        Code identifying why a product was not published in a publish request. -
        `NotOwned`: the product ID does not belong to your account. -
        `ScoreChangedDuringSubmission`: the product's Eco-Score changed between
        the eligibility check and the portal submission; retry the publish. -
        `GroupAbortedDueToPeerDrift`: another product submitted in the same
        batch changed during submission; the whole batch was rolled back. -
        `WithinThreeMonthLock`: the product was published within the last 3
        months and cannot be republished yet (see `nextEligibleAt`). -
        `EligibilityFailure`: a structural eligibility check failed (e.g.
        missing GTIN, unsupported material). The corresponding `message`
        explains which check failed.
      enum:
        - NotOwned
        - ScoreChangedDuringSubmission
        - GroupAbortedDueToPeerDrift
        - WithinThreeMonthLock
        - EligibilityFailure
      type: string
  securitySchemes:
    sec0:
      type: apiKey
      in: header
      name: x-api-key
    sec1:
      type: apiKey
      in: header
      name: x-developer-request-token

````