{
  "openapi": "3.1.0",
  "info": {
    "title": "Dango Client API",
    "description": "API externe org-scoped d'enrichissement produit. Chaque appel est authentifié\npar une clé d'API d'organisation (Authorization: Bearer dk_org_…).\n"
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Clé d'API d'organisation : Authorization: Bearer dk_org_…"
      }
    },
    "schemas": {
      "api.v1.AddActivitiesRequest": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "title": "project_id",
            "description": "project_id is the sqid returned by CreateProject/ImportCSV."
          },
          "activities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/api.v1.ImportActivity"
            },
            "title": "activities"
          }
        },
        "title": "AddActivitiesRequest",
        "additionalProperties": false
      },
      "api.v1.AddActivitiesResponse": {
        "type": "object",
        "properties": {
          "staged": {
            "type": [
              "integer",
              "string"
            ],
            "title": "staged",
            "format": "int64",
            "description": "staged is the total number of staged rows on the project after this call."
          }
        },
        "title": "AddActivitiesResponse",
        "additionalProperties": false
      },
      "api.v1.CreateProjectRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "title": "name"
          }
        },
        "title": "CreateProjectRequest",
        "additionalProperties": false
      },
      "api.v1.CreateProjectResponse": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "title": "project_id",
            "description": "project_id is a short opaque identifier (sqid) — never a raw UUID. Pass it\n back verbatim to AddActivities/Submit/GetProgress/ExportCSV."
          }
        },
        "title": "CreateProjectResponse",
        "additionalProperties": false
      },
      "api.v1.ExportCSVRequest": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "title": "project_id",
            "description": "project_id is the sqid returned by CreateProject/ImportCSV."
          }
        },
        "title": "ExportCSVRequest",
        "additionalProperties": false
      },
      "api.v1.ExportCSVResponse": {
        "type": "object",
        "properties": {
          "downloadUrl": {
            "type": "string",
            "title": "download_url"
          },
          "expiresAt": {
            "type": "string",
            "title": "expires_at",
            "description": "expires_at is the RFC3339 instant the presigned URL stops working."
          }
        },
        "title": "ExportCSVResponse",
        "additionalProperties": false
      },
      "api.v1.GetProgressRequest": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "title": "project_id",
            "description": "project_id is the sqid returned by CreateProject/ImportCSV."
          }
        },
        "title": "GetProgressRequest",
        "additionalProperties": false
      },
      "api.v1.GetProgressResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "title": "status",
            "description": "status is one of \"pending\", \"enriching\", \"completed\", \"failed\"."
          },
          "totalLines": {
            "type": [
              "integer",
              "string"
            ],
            "title": "total_lines",
            "format": "int64"
          },
          "enriched": {
            "type": [
              "integer",
              "string"
            ],
            "title": "enriched",
            "format": "int64"
          },
          "inProgress": {
            "type": [
              "integer",
              "string"
            ],
            "title": "in_progress",
            "format": "int64"
          },
          "failed": {
            "type": [
              "integer",
              "string"
            ],
            "title": "failed",
            "format": "int64"
          },
          "submittedAt": {
            "type": "string",
            "title": "submitted_at",
            "description": "submitted_at / completed_at are RFC3339 timestamps, empty when not set."
          },
          "completedAt": {
            "type": "string",
            "title": "completed_at"
          }
        },
        "title": "GetProgressResponse",
        "additionalProperties": false
      },
      "api.v1.ImportActivity": {
        "type": "object",
        "properties": {
          "designation": {
            "type": "string",
            "title": "designation"
          },
          "supplier": {
            "type": "string",
            "title": "supplier"
          },
          "unitPrice": {
            "type": "string",
            "title": "unit_price"
          },
          "currency": {
            "type": "string",
            "title": "currency"
          },
          "quantity": {
            "type": "string",
            "title": "quantity"
          },
          "unit": {
            "type": "string",
            "title": "unit"
          },
          "purchaseDate": {
            "type": "string",
            "title": "purchase_date"
          },
          "weight": {
            "type": "string",
            "title": "weight"
          },
          "notes": {
            "type": "string",
            "title": "notes"
          },
          "category": {
            "type": "string",
            "title": "category"
          }
        },
        "title": "ImportActivity",
        "additionalProperties": false,
        "description": "ImportActivity mirrors the 10-column agent import template (designation required)."
      },
      "api.v1.ImportCSVRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "title": "name"
          },
          "csv": {
            "type": "string",
            "title": "csv",
            "format": "byte"
          },
          "categoryMode": {
            "type": "string",
            "title": "category_mode",
            "description": "category_mode is one of \"ademe\" (default), \"client\", \"referential\"."
          }
        },
        "title": "ImportCSVRequest",
        "additionalProperties": false
      },
      "api.v1.ImportCSVResponse": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "title": "project_id",
            "description": "project_id is a short opaque identifier (sqid) — never a raw UUID."
          }
        },
        "title": "ImportCSVResponse",
        "additionalProperties": false
      },
      "api.v1.SubmitRequest": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "title": "project_id",
            "description": "project_id is the sqid returned by CreateProject/ImportCSV."
          },
          "webhookUrl": {
            "type": "string",
            "title": "webhook_url",
            "description": "webhook_url, when set, receives a signed POST when enrichment completes."
          }
        },
        "title": "SubmitRequest",
        "additionalProperties": false
      },
      "api.v1.SubmitResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "title": "status"
          }
        },
        "title": "SubmitResponse",
        "additionalProperties": false
      },
      "connect-protocol-version": {
        "type": "number",
        "title": "Connect-Protocol-Version",
        "enum": [
          1
        ],
        "description": "Define the version of the Connect protocol",
        "const": 1
      },
      "connect-timeout-header": {
        "type": "number",
        "title": "Connect-Timeout-Ms",
        "description": "Define the timeout, in ms"
      },
      "connect.error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "examples": [
              "not_found"
            ],
            "enum": [
              "canceled",
              "unknown",
              "invalid_argument",
              "deadline_exceeded",
              "not_found",
              "already_exists",
              "permission_denied",
              "resource_exhausted",
              "failed_precondition",
              "aborted",
              "out_of_range",
              "unimplemented",
              "internal",
              "unavailable",
              "data_loss",
              "unauthenticated"
            ],
            "description": "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
          },
          "message": {
            "type": "string",
            "description": "A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client."
          },
          "details": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/connect.error_details.Any"
            },
            "description": "A list of messages that carry the error details. There is no limit on the number of messages."
          }
        },
        "title": "Connect Error",
        "additionalProperties": true,
        "description": "Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation"
      },
      "connect.error_details.Any": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "A URL that acts as a globally unique identifier for the type of the serialized message. For example: `type.googleapis.com/google.rpc.ErrorInfo`. This is used to determine the schema of the data in the `value` field and is the discriminator for the `debug` field."
          },
          "value": {
            "type": "string",
            "format": "binary",
            "description": "The Protobuf message, serialized as bytes and base64-encoded. The specific message type is identified by the `type` field."
          },
          "debug": {
            "oneOf": [
              {
                "type": "object",
                "title": "Any",
                "additionalProperties": true,
                "description": "Detailed error information."
              }
            ],
            "discriminator": {
              "propertyName": "type"
            },
            "title": "Debug",
            "description": "Deserialized error detail payload. The 'type' field indicates the schema. This field is for easier debugging and should not be relied upon for application logic."
          }
        },
        "additionalProperties": true,
        "description": "Contains an arbitrary serialized message along with a @type that describes the type of the serialized message, with an additional debug field for ConnectRPC error details."
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/api.v1.Service/AddActivities": {
      "post": {
        "tags": [
          "api.v1.Service"
        ],
        "summary": "AddActivities",
        "description": "AddActivities stages rows on an unsealed project. Rows collapse at submit.",
        "operationId": "api.v1.Service.AddActivities",
        "parameters": [
          {
            "name": "Connect-Protocol-Version",
            "in": "header",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/connect-protocol-version"
            }
          },
          {
            "name": "Connect-Timeout-Ms",
            "in": "header",
            "schema": {
              "$ref": "#/components/schemas/connect-timeout-header"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/api.v1.AddActivitiesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/connect.error"
                }
              }
            }
          },
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/api.v1.AddActivitiesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api.v1.Service/CreateProject": {
      "post": {
        "tags": [
          "api.v1.Service"
        ],
        "summary": "CreateProject",
        "description": "CreateProject creates an empty project owned by the caller's organization.",
        "operationId": "api.v1.Service.CreateProject",
        "parameters": [
          {
            "name": "Connect-Protocol-Version",
            "in": "header",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/connect-protocol-version"
            }
          },
          {
            "name": "Connect-Timeout-Ms",
            "in": "header",
            "schema": {
              "$ref": "#/components/schemas/connect-timeout-header"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/api.v1.CreateProjectRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/connect.error"
                }
              }
            }
          },
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/api.v1.CreateProjectResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api.v1.Service/ExportCSV": {
      "post": {
        "tags": [
          "api.v1.Service"
        ],
        "summary": "ExportCSV",
        "description": "ExportCSV returns a short-lived presigned URL to download the project CSV.",
        "operationId": "api.v1.Service.ExportCSV",
        "parameters": [
          {
            "name": "Connect-Protocol-Version",
            "in": "header",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/connect-protocol-version"
            }
          },
          {
            "name": "Connect-Timeout-Ms",
            "in": "header",
            "schema": {
              "$ref": "#/components/schemas/connect-timeout-header"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/api.v1.ExportCSVRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/connect.error"
                }
              }
            }
          },
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/api.v1.ExportCSVResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api.v1.Service/GetProgress": {
      "post": {
        "tags": [
          "api.v1.Service"
        ],
        "summary": "GetProgress",
        "description": "GetProgress returns aggregate enrichment counters for a project.",
        "operationId": "api.v1.Service.GetProgress",
        "parameters": [
          {
            "name": "Connect-Protocol-Version",
            "in": "header",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/connect-protocol-version"
            }
          },
          {
            "name": "Connect-Timeout-Ms",
            "in": "header",
            "schema": {
              "$ref": "#/components/schemas/connect-timeout-header"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/api.v1.GetProgressRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/connect.error"
                }
              }
            }
          },
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/api.v1.GetProgressResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api.v1.Service/ImportCSV": {
      "post": {
        "tags": [
          "api.v1.Service"
        ],
        "summary": "ImportCSV",
        "description": "ImportCSV creates a project from a CSV upload and immediately seals it\n (implicit submit) so enrichment starts at once.",
        "operationId": "api.v1.Service.ImportCSV",
        "parameters": [
          {
            "name": "Connect-Protocol-Version",
            "in": "header",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/connect-protocol-version"
            }
          },
          {
            "name": "Connect-Timeout-Ms",
            "in": "header",
            "schema": {
              "$ref": "#/components/schemas/connect-timeout-header"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/api.v1.ImportCSVRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/connect.error"
                }
              }
            }
          },
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/api.v1.ImportCSVResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api.v1.Service/Submit": {
      "post": {
        "tags": [
          "api.v1.Service"
        ],
        "summary": "Submit",
        "description": "Submit seals a project's staged lines and starts enrichment. Idempotent.",
        "operationId": "api.v1.Service.Submit",
        "parameters": [
          {
            "name": "Connect-Protocol-Version",
            "in": "header",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/connect-protocol-version"
            }
          },
          {
            "name": "Connect-Timeout-Ms",
            "in": "header",
            "schema": {
              "$ref": "#/components/schemas/connect-timeout-header"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/api.v1.SubmitRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/connect.error"
                }
              }
            }
          },
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/api.v1.SubmitResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "api.v1.Service",
      "description": "Service is the organization-scoped client API. Every RPC is authenticated by\n an organization API key (Authorization: Bearer dk_org_…) and authorizes by the\n key's organization (see internal/api auth interceptor)."
    }
  ]
}