Français
Analyseur de boîte
Les routes sont relatives à <PUBLIC_BASE_URL> ; les corps de requête et de réponse sont en JSON sauf mention contraire. L’authentification, les portées, la pagination et le format des erreurs sont décrits dans les guides de l’API REST.
POST /api/v1/mailboxes/{id}/analyze
Analyser une boîte
Planifie une analyse du courrier miroir de la boîte : groupes d’expéditeurs, volumes, et les opportunités d’automatisation qu’un modèle y voit. 202, même quand le rapport du jour existe déjà (reused: true) sauf force. La boîte d’un autre membre est un 404.
Accès — Session de membre ou clé d’API portant analyzer:write.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
force | boolean | non |
windowDays | 30 | 90 | 180 | 365 | non |
minGroupVolume | integer | non |
Schéma JSON
json
{
"type": "object",
"properties": {
"force": { "default": false, "type": "boolean" },
"windowDays": {
"anyOf": [
{ "type": "number", "const": 30 },
{ "type": "number", "const": 90 },
{ "type": "number", "const": 180 },
{ "type": "number", "const": 365 }
]
},
"minGroupVolume": { "type": "integer", "minimum": 1, "maximum": 1000 }
}
}Réponses
202 — La référence du rapport, en attente ou réutilisé.
| Champ | Type | Requis |
|---|---|---|
report | object | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"report": {
"type": "object",
"properties": {
"id": { "type": "string" },
"mailboxId": { "type": "string" },
"status": { "type": "string", "enum": [ "pending", "running", "done", "failed" ] },
"createdAt": { "type": "string" },
"generatedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"reused": { "type": "boolean" }
},
"required": [ "id", "mailboxId", "status", "createdAt", "generatedAt", "reused" ],
"additionalProperties": false
}
},
"required": [ "report" ],
"additionalProperties": false
}400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Cette opération accepte un en-tête Idempotency-Key : rejouer la même requête avec la même clé rend la réponse d’origine au lieu d’agir deux fois. Voir Idempotence.
Codes d’erreur — request.bad_request, analyzer.mailbox_not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/mailboxes/{id}/analyzer/report
Lire le dernier rapport d’une boîte
Le dernier rapport, quel que soit son statut. analyzer.report_not_found quand la boîte n’a jamais été analysée, distinct du 404 d’une boîte hors périmètre. Les transcriptions brutes du modèle ne sont rendues qu’aux administrateurs.
Accès — Session de membre ou clé d’API portant analyzer:read.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Réponses
200 — Le rapport.
| Champ | Type | Requis |
|---|---|---|
report | object | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"report": {
"type": "object",
"properties": {
"id": { "type": "string" },
"mailboxId": { "type": "string" },
"status": { "type": "string", "enum": [ "pending", "running", "done", "failed" ] },
"createdAt": { "type": "string" },
"generatedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"options": {
"type": "object",
"properties": {
"windowDays": {
"anyOf": [
{ "type": "number", "const": 30 },
{ "type": "number", "const": 90 },
{ "type": "number", "const": 180 },
{ "type": "number", "const": 365 }
]
},
"minGroupVolume": { "type": "integer", "minimum": 1, "maximum": 1000 }
},
"additionalProperties": false
},
"body": {
"anyOf": [
{
"type": "object",
"properties": {
"stats": {
"type": "object",
"properties": {
"received30d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"excluded30d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"unmatched30d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"dispatched30d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"messages30d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"messages90d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"messages365d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"senders": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"domains": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"peakHours": {
"type": "array",
"items": {
"type": "object",
"properties": {
"hour": { "type": "integer", "minimum": 0, "maximum": 23 },
"volume": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "hour", "volume" ],
"additionalProperties": false
}
},
"groups": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"groupsAnalyzed": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"llmOutcome": {
"oneOf": [
{
"type": "object",
"properties": {
"status": { "type": "string", "const": "ran" },
"usage": {
"type": "object",
"properties": {
"model": { "type": "string" },
"inputTokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"outputTokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"reasoningTokens": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"costUsd": {
"anyOf": [ { "type": "number" }, { "type": "null" } ]
}
},
"required": [
"model",
"inputTokens",
"outputTokens",
"reasoningTokens",
"costUsd"
],
"additionalProperties": false
},
"batches": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"failedBatches": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"groupsAttempted": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"groupsAnswered": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"failure": {
"anyOf": [
{
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string", "maxLength": 300 }
},
"required": [ "code", "message" ],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [
"status",
"usage",
"batches",
"failedBatches",
"groupsAttempted",
"groupsAnswered",
"failure"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"status": { "type": "string", "const": "no_provider" }
},
"required": [ "status" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"status": { "type": "string", "const": "nothing_to_analyze" }
},
"required": [ "status" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"status": { "type": "string", "const": "failed" },
"code": { "type": "string" },
"message": { "type": "string", "maxLength": 300 },
"batches": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"failedBatches": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"groupsAttempted": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"groupsAnswered": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"usage": {
"anyOf": [
{
"type": "object",
"properties": {
"model": { "type": "string" },
"inputTokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"outputTokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"reasoningTokens": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"costUsd": {
"anyOf": [
{ "type": "number" },
{ "type": "null" }
]
}
},
"required": [
"model",
"inputTokens",
"outputTokens",
"reasoningTokens",
"costUsd"
],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [
"status",
"code",
"message",
"batches",
"failedBatches",
"groupsAttempted",
"groupsAnswered",
"usage"
],
"additionalProperties": false
}
]
}
},
"required": [
"received30d",
"excluded30d",
"unmatched30d",
"dispatched30d",
"messages30d",
"messages90d",
"messages365d",
"senders",
"domains",
"peakHours",
"groups",
"groupsAnalyzed",
"llmOutcome"
],
"additionalProperties": false
},
"window": {
"type": "object",
"properties": {
"days": {
"anyOf": [
{ "type": "number", "const": 30 },
{ "type": "number", "const": 90 },
{ "type": "number", "const": 180 },
{ "type": "number", "const": 365 }
]
},
"reason": {
"type": "string",
"enum": [ "target_reached", "capped", "member_choice" ]
},
"targetMessages": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"messages": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"excludedByScope": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"candidates": {
"type": "array",
"items": {
"type": "object",
"properties": {
"days": {
"anyOf": [
{ "type": "number", "const": 30 },
{ "type": "number", "const": 90 },
{ "type": "number", "const": 180 },
{ "type": "number", "const": 365 }
]
},
"messages": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "days", "messages" ],
"additionalProperties": false
}
}
},
"required": [
"days",
"reason",
"targetMessages",
"messages",
"excludedByScope",
"candidates"
],
"additionalProperties": false
},
"thresholds": {
"type": "object",
"properties": {
"minGroupVolume": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"mode": { "type": "string", "enum": [ "auto", "member_choice" ] },
"floor": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"share": { "type": "number", "minimum": 0, "maximum": 1 },
"maxGroupsAnalyzed": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"maxOpportunities": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"minGroupVolume",
"mode",
"floor",
"share",
"maxGroupsAnalyzed",
"maxOpportunities"
],
"additionalProperties": false
},
"coverage": {
"type": "object",
"properties": {
"messages": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"covered": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"ratio": { "type": "number", "minimum": 0, "maximum": 1 },
"publishedWorkflows": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"workflows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"messages": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "id", "name", "messages" ],
"additionalProperties": false
}
},
"bodyApproximated": { "type": "boolean" }
},
"required": [
"messages",
"covered",
"ratio",
"publishedWorkflows",
"workflows",
"bodyApproximated"
],
"additionalProperties": false
},
"groups": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": { "type": "string" },
"domain": { "type": "string" },
"publicDomains": { "type": "array", "items": { "type": "string" } },
"signal": {
"type": "string",
"enum": [ "newsletter", "automated", "auto", "human" ]
},
"subjectShape": { "type": "string" },
"topic": {
"anyOf": [
{
"type": "string",
"enum": [
"job_application",
"interview",
"purchase_offer",
"quote_request",
"accounting_documents",
"tax",
"invoice",
"refund",
"order",
"parcel",
"reservation",
"visit",
"meeting",
"volunteering",
"membership",
"donation",
"registration",
"signature",
"contract",
"support",
"partnership",
"reminder",
"contact_request"
]
},
{ "type": "null" }
]
},
"label": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"note": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"volume": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"monthlyVolume": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"unread": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"withAttachments": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"senders": { "type": "array", "items": { "type": "string" } },
"sampleSubject": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"verdict": {
"type": "string",
"enum": [
"proposed",
"covered",
"below_threshold",
"over_limit",
"nothing_to_automate",
"proposal_rejected",
"no_answer",
"not_analyzed",
"ranked_out"
]
},
"reason": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"rejection": {
"anyOf": [
{
"type": "object",
"properties": {
"malformed": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": {
"type": "string",
"enum": [ "rejected", "adjusted" ]
},
"code": {
"type": "string",
"enum": [
"invalid_shape",
"unknown_node",
"forbidden_node",
"duplicate_step",
"dangling_step",
"invalid_port",
"unknown_param",
"invalid_param",
"unknown_table",
"unknown_column",
"invalid_step",
"sender_not_observed",
"public_domain_sender",
"trigger_too_broad",
"send_forced_to_draft",
"table_key_added",
"no_step",
"malformed_proposal",
"port_normalized",
"template_kept_literal",
"step_bypassed",
"trigger_simplified",
"value_clamped",
"human_mail_kept",
"rule_instead_of_ai",
"reply_to_automated"
]
},
"stepId": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
},
"nodeType": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
},
"param": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
},
"detail": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
}
},
"required": [
"severity",
"code",
"stepId",
"nodeType",
"param",
"detail"
],
"additionalProperties": false
}
}
},
"required": [ "malformed", "issues" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"llmError": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"coverage": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [ "covered", "partial", "none" ]
},
"covered": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"workflows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"messages": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "id", "name", "messages" ],
"additionalProperties": false
}
}
},
"required": [ "status", "covered", "workflows" ],
"additionalProperties": false
},
"opportunityIds": { "type": "array", "items": { "type": "string" } }
},
"required": [
"key",
"domain",
"publicDomains",
"signal",
"subjectShape",
"topic",
"label",
"note",
"volume",
"monthlyVolume",
"unread",
"withAttachments",
"senders",
"sampleSubject",
"verdict",
"reason",
"rejection",
"llmError",
"coverage",
"opportunityIds"
],
"additionalProperties": false
}
},
"opportunities": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1 },
"groupKey": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"origin": {
"oneOf": [
{
"type": "object",
"properties": {
"source": { "type": "string", "const": "model" },
"title": { "type": "string", "minLength": 1 },
"description": { "type": "string" },
"workflowName": {
"type": "string",
"minLength": 1,
"maxLength": 60
},
"benefitRationale": { "type": "string" }
},
"required": [
"source",
"title",
"description",
"workflowName",
"benefitRationale"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"source": { "type": "string", "const": "template" },
"template": {
"type": "string",
"enum": [
"newsletter_cleanup",
"auto_archive_notifications",
"categorize",
"vip_flag",
"draft_reply"
]
},
"params": {
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {
"anyOf": [ { "type": "string" }, { "type": "number" } ]
}
},
"fallback": {
"anyOf": [
{
"type": "object",
"properties": {
"reason": {
"type": "string",
"enum": [ "no_answer", "proposal_rejected" ]
},
"llmError": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": {
"type": "string",
"enum": [ "rejected", "adjusted" ]
},
"code": {
"type": "string",
"enum": [
"invalid_shape",
"unknown_node",
"forbidden_node",
"duplicate_step",
"dangling_step",
"invalid_port",
"unknown_param",
"invalid_param",
"unknown_table",
"unknown_column",
"invalid_step",
"sender_not_observed",
"public_domain_sender",
"trigger_too_broad",
"send_forced_to_draft",
"table_key_added",
"no_step",
"malformed_proposal",
"port_normalized",
"template_kept_literal",
"step_bypassed",
"trigger_simplified",
"value_clamped",
"human_mail_kept",
"rule_instead_of_ai",
"reply_to_automated"
]
},
"stepId": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
},
"nodeType": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
},
"param": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
},
"detail": {
"anyOf": [
{ "type": "string" },
{ "type": "null" }
]
}
},
"required": [
"severity",
"code",
"stepId",
"nodeType",
"param",
"detail"
],
"additionalProperties": false
}
}
},
"required": [ "reason", "llmError", "issues" ],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [ "source", "template", "params", "fallback" ],
"additionalProperties": false
}
]
},
"volume": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"monthlyVolume": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"windowDays": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"minutesPerEmail": { "type": "number", "minimum": 0 },
"minutesPerMonth": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"senders": { "type": "array", "items": { "type": "string" } },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"nodeId": { "type": "string" },
"type": { "type": "string" },
"name": { "type": "string" },
"label": {
"type": "object",
"properties": {
"fr": { "type": "string" },
"en": { "type": "string" }
},
"required": [ "fr", "en" ],
"additionalProperties": false
},
"effect": {
"type": "string",
"enum": [ "none", "external_write", "send" ]
}
},
"required": [ "nodeId", "type", "name", "label", "effect" ],
"additionalProperties": false
}
},
"prerequisites": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "table" },
"ref": { "type": "string" },
"slug": { "type": "string" },
"name": { "type": "string" },
"columns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Machine key: lowercase, a-z0-9_."
},
"label": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"type": {
"type": "string",
"enum": [
"text",
"number",
"boolean",
"date",
"datetime",
"select",
"email"
]
},
"isKey": {
"type": "boolean",
"description": "Part of the row key used to find/update a row."
}
},
"required": [ "key", "label", "type", "isKey" ],
"additionalProperties": false
}
}
},
"required": [ "kind", "ref", "slug", "name", "columns" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "connection" },
"connection": { "type": "string" },
"credentialType": { "type": "string" },
"capability": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"nodeId": { "type": "string" },
"nodeType": { "type": "string" }
},
"required": [
"kind",
"connection",
"credentialType",
"capability",
"nodeId",
"nodeType"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "complete" },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" },
"param": { "type": "string" },
"label": {
"type": "object",
"properties": {
"fr": { "type": "string" },
"en": { "type": "string" }
},
"required": [ "fr", "en" ],
"additionalProperties": false
}
},
"required": [ "kind", "nodeId", "nodeType", "param", "label" ],
"additionalProperties": false
}
]
}
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": {
"type": "string",
"enum": [ "rejected", "adjusted" ]
},
"code": {
"type": "string",
"enum": [
"invalid_shape",
"unknown_node",
"forbidden_node",
"duplicate_step",
"dangling_step",
"invalid_port",
"unknown_param",
"invalid_param",
"unknown_table",
"unknown_column",
"invalid_step",
"sender_not_observed",
"public_domain_sender",
"trigger_too_broad",
"send_forced_to_draft",
"table_key_added",
"no_step",
"malformed_proposal",
"port_normalized",
"template_kept_literal",
"step_bypassed",
"trigger_simplified",
"value_clamped",
"human_mail_kept",
"rule_instead_of_ai",
"reply_to_automated"
]
},
"stepId": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"nodeType": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"param": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"detail": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
}
},
"required": [
"severity",
"code",
"stepId",
"nodeType",
"param",
"detail"
],
"additionalProperties": false
}
},
"proposedWorkflow": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": {
"type": "integer",
"minimum": 1,
"maximum": 10
},
"delayMs": {
"type": "integer",
"minimum": 1000,
"maximum": 3600000
}
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": {
"type": "integer",
"minimum": 5000,
"maximum": 1800000
},
"position": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [
"id",
"type",
"version",
"name",
"params",
"onError"
],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": {
"type": "string",
"enum": [ "data", "service" ]
}
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"text": {
"default": "",
"type": "string",
"maxLength": 4000
},
"position": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": {
"type": "number",
"minimum": 120,
"maximum": 2000
},
"height": {
"type": "number",
"minimum": 80,
"maximum": 2000
}
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [
"jaune",
"menthe",
"ciel",
"rose",
"lavande"
]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": {
"type": "string",
"minLength": 1,
"maxLength": 64
}
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
}
},
"required": [
"id",
"groupKey",
"origin",
"volume",
"monthlyVolume",
"windowDays",
"minutesPerEmail",
"minutesPerMonth",
"senders",
"confidence",
"steps",
"prerequisites",
"issues",
"proposedWorkflow"
],
"additionalProperties": false
}
},
"topSenders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"email": { "type": "string" },
"domain": { "type": "string" },
"name": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"volume30d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"volume90d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"volume365d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"unreadRatio": { "type": "number", "minimum": 0, "maximum": 1 },
"replyRatio": { "type": "number", "minimum": 0, "maximum": 1 },
"replies90d": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"mailingList": { "type": "boolean" },
"noReply": { "type": "boolean" },
"autoReply": { "type": "boolean" },
"lastReceivedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"email",
"domain",
"name",
"volume30d",
"volume90d",
"volume365d",
"unreadRatio",
"replyRatio",
"replies90d",
"mailingList",
"noReply",
"autoReply",
"lastReceivedAt"
],
"additionalProperties": false
}
},
"llmTranscripts": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"batch": { "type": "string" },
"groupKeys": { "type": "array", "items": { "type": "string" } },
"status": { "type": "string", "enum": [ "answered", "failed" ] },
"failureCode": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"usage": {
"anyOf": [
{
"type": "object",
"properties": {
"model": { "type": "string" },
"inputTokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"outputTokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"reasoningTokens": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"costUsd": {
"anyOf": [ { "type": "number" }, { "type": "null" } ]
}
},
"required": [
"model",
"inputTokens",
"outputTokens",
"reasoningTokens",
"costUsd"
],
"additionalProperties": false
},
{ "type": "null" }
]
},
"durationMs": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"reasoningEffort": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"excerpt": { "type": "string", "maxLength": 4001 },
"truncated": { "type": "boolean" }
},
"required": [
"batch",
"groupKeys",
"status",
"failureCode",
"usage",
"durationMs",
"reasoningEffort",
"excerpt",
"truncated"
],
"additionalProperties": false
}
},
{ "type": "null" }
]
}
},
"required": [
"stats",
"window",
"thresholds",
"coverage",
"groups",
"opportunities",
"topSenders",
"llmTranscripts"
],
"additionalProperties": false
},
{ "type": "null" }
]
},
"error": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"id",
"mailboxId",
"status",
"createdAt",
"generatedAt",
"options",
"body",
"error"
],
"additionalProperties": false
}
},
"required": [ "report" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — analyzer.mailbox_not_found, analyzer.report_not_found, analyzer.report_outdated. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/mailboxes/{id}/analyzer/estimate
Estimer le coût d’une analyse
Rejoue la vraie clusterisation avec les réglages donnés, sans appeler aucun fournisseur : combien de mails partiraient au modèle, chez quel fournisseur, sur quel modèle, et pour combien. 200 même sans fournisseur configuré (llmConfigured: false).
Accès — Session de membre ou clé d’API portant analyzer:read.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
windowDays | requête | number | non |
minGroupVolume | requête | integer | non |
Réponses
200 — L’estimation.
| Champ | Type | Requis |
|---|---|---|
estimate | object | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"estimate": {
"type": "object",
"properties": {
"llmConfigured": { "type": "boolean" },
"provider": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"model": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"windowDays": {
"anyOf": [
{ "type": "number", "const": 30 },
{ "type": "number", "const": 90 },
{ "type": "number", "const": 180 },
{ "type": "number", "const": 365 }
]
},
"scannedMessages": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"groups": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"groupsAnalyzed": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"minGroupVolume": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"sampledMessages": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"catalogNodes": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"batches": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"estimatedInputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"sharedPrefixTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"estimatedOutputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"maxOutputTokens": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"estimatedCostUsd": { "anyOf": [ { "type": "number" }, { "type": "null" } ] }
},
"required": [
"llmConfigured",
"provider",
"model",
"windowDays",
"scannedMessages",
"groups",
"groupsAnalyzed",
"minGroupVolume",
"sampledMessages",
"catalogNodes",
"batches",
"estimatedInputTokens",
"sharedPrefixTokens",
"estimatedOutputTokens",
"maxOutputTokens",
"estimatedCostUsd"
],
"additionalProperties": false
}
},
"required": [ "estimate" ],
"additionalProperties": false
}400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — request.bad_request, analyzer.mailbox_not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
POST /api/v1/mailboxes/{id}/analyzer/groups/rerun
Relancer la passe IA sur un groupe
Réinterroge le modèle sur un seul groupe d’expéditeurs du dernier rapport et rend le rapport MIS À JOUR. 409 analyzer.report_busy pendant qu’une analyse tourne ou qu’une autre relance vient d’écrire ; 409 analyzer.llm_unavailable quand aucun fournisseur ne répond.
Accès — Session de membre ou clé d’API portant analyzer:write.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
groupKey | string | oui |
Schéma JSON
json
{
"type": "object",
"properties": { "groupKey": { "type": "string", "minLength": 1, "maxLength": 600 } },
"required": [ "groupKey" ]
}Réponses
200 — Le rapport, mis à jour.
| Champ | Type | Requis |
|---|---|---|
report | object | oui |
Même schéma que GET /api/v1/mailboxes/{id}/analyzer/report.
400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Cette opération accepte un en-tête Idempotency-Key : rejouer la même requête avec la même clé rend la réponse d’origine au lieu d’agir deux fois. Voir Idempotence.
Codes d’erreur — request.bad_request, analyzer.mailbox_not_found, analyzer.report_not_found, analyzer.group_not_found, analyzer.report_busy, analyzer.llm_unavailable. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
POST /api/v1/mailboxes/{id}/analyzer/opportunities/{opportunityId}/create
Créer un brouillon depuis une opportunité
Le serveur relit l’opportunité dans le dernier rapport de la boîte et construit lui-même le brouillon ; la requête ne porte qu’un nom et l’accord pour créer les Tables manquantes. 409 analyzer.tables_required quand une Table manque sans accord ; 403 analyzer.table_creation_forbidden quand la créer est un geste d’administrateur.
Accès — Session de membre ou clé d’API portant analyzer:write.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
opportunityId | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
name | string | oui |
createTables | boolean | non |
Schéma JSON
json
{
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"createTables": { "default": false, "type": "boolean" }
},
"required": [ "name" ]
}Réponses
201 — Le nouveau workflow, et les Tables créées avec lui.
| Champ | Type | Requis |
|---|---|---|
workflowId | string | oui |
name | string | oui |
tables | object[] | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"workflowId": { "type": "string" },
"name": { "type": "string" },
"tables": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"slug": { "type": "string" },
"name": { "type": "string" }
},
"required": [ "id", "slug", "name" ],
"additionalProperties": false
}
}
},
"required": [ "workflowId", "name", "tables" ],
"additionalProperties": false
}400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Cette opération accepte un en-tête Idempotency-Key : rejouer la même requête avec la même clé rend la réponse d’origine au lieu d’agir deux fois. Voir Idempotence.
Codes d’erreur — request.bad_request, analyzer.mailbox_not_found, analyzer.report_not_found, analyzer.opportunity_not_found, analyzer.tables_required, analyzer.table_creation_forbidden. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/analyzer/suggestions
Lister mes suggestions actives
Les suggestions continues, toutes boîtes du membre confondues. Sans pagination : la liste est bornée par le service à quelques dizaines au plus.
Accès — Session de membre ou clé d’API portant analyzer:read.
Réponses
200 — Les suggestions.
| Champ | Type | Requis |
|---|---|---|
suggestions | object[] | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"suggestions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1 },
"groupKey": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"origin": {
"oneOf": [
{
"type": "object",
"properties": {
"source": { "type": "string", "const": "model" },
"title": { "type": "string", "minLength": 1 },
"description": { "type": "string" },
"workflowName": { "type": "string", "minLength": 1, "maxLength": 60 },
"benefitRationale": { "type": "string" }
},
"required": [
"source",
"title",
"description",
"workflowName",
"benefitRationale"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"source": { "type": "string", "const": "template" },
"template": {
"type": "string",
"enum": [
"newsletter_cleanup",
"auto_archive_notifications",
"categorize",
"vip_flag",
"draft_reply"
]
},
"params": {
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": { "anyOf": [ { "type": "string" }, { "type": "number" } ] }
},
"fallback": {
"anyOf": [
{
"type": "object",
"properties": {
"reason": {
"type": "string",
"enum": [ "no_answer", "proposal_rejected" ]
},
"llmError": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": {
"type": "string",
"enum": [ "rejected", "adjusted" ]
},
"code": {
"type": "string",
"enum": [
"invalid_shape",
"unknown_node",
"forbidden_node",
"duplicate_step",
"dangling_step",
"invalid_port",
"unknown_param",
"invalid_param",
"unknown_table",
"unknown_column",
"invalid_step",
"sender_not_observed",
"public_domain_sender",
"trigger_too_broad",
"send_forced_to_draft",
"table_key_added",
"no_step",
"malformed_proposal",
"port_normalized",
"template_kept_literal",
"step_bypassed",
"trigger_simplified",
"value_clamped",
"human_mail_kept",
"rule_instead_of_ai",
"reply_to_automated"
]
},
"stepId": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"nodeType": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"param": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"detail": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
}
},
"required": [
"severity",
"code",
"stepId",
"nodeType",
"param",
"detail"
],
"additionalProperties": false
}
}
},
"required": [ "reason", "llmError", "issues" ],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [ "source", "template", "params", "fallback" ],
"additionalProperties": false
}
]
},
"volume": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"monthlyVolume": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"windowDays": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"minutesPerEmail": { "type": "number", "minimum": 0 },
"minutesPerMonth": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"senders": { "type": "array", "items": { "type": "string" } },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"nodeId": { "type": "string" },
"type": { "type": "string" },
"name": { "type": "string" },
"label": {
"type": "object",
"properties": { "fr": { "type": "string" }, "en": { "type": "string" } },
"required": [ "fr", "en" ],
"additionalProperties": false
},
"effect": {
"type": "string",
"enum": [ "none", "external_write", "send" ]
}
},
"required": [ "nodeId", "type", "name", "label", "effect" ],
"additionalProperties": false
}
},
"prerequisites": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "table" },
"ref": { "type": "string" },
"slug": { "type": "string" },
"name": { "type": "string" },
"columns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Machine key: lowercase, a-z0-9_."
},
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
"type": {
"type": "string",
"enum": [
"text",
"number",
"boolean",
"date",
"datetime",
"select",
"email"
]
},
"isKey": {
"type": "boolean",
"description": "Part of the row key used to find/update a row."
}
},
"required": [ "key", "label", "type", "isKey" ],
"additionalProperties": false
}
}
},
"required": [ "kind", "ref", "slug", "name", "columns" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "connection" },
"connection": { "type": "string" },
"credentialType": { "type": "string" },
"capability": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" }
},
"required": [
"kind",
"connection",
"credentialType",
"capability",
"nodeId",
"nodeType"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "complete" },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" },
"param": { "type": "string" },
"label": {
"type": "object",
"properties": { "fr": { "type": "string" }, "en": { "type": "string" } },
"required": [ "fr", "en" ],
"additionalProperties": false
}
},
"required": [ "kind", "nodeId", "nodeType", "param", "label" ],
"additionalProperties": false
}
]
}
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": { "type": "string", "enum": [ "rejected", "adjusted" ] },
"code": {
"type": "string",
"enum": [
"invalid_shape",
"unknown_node",
"forbidden_node",
"duplicate_step",
"dangling_step",
"invalid_port",
"unknown_param",
"invalid_param",
"unknown_table",
"unknown_column",
"invalid_step",
"sender_not_observed",
"public_domain_sender",
"trigger_too_broad",
"send_forced_to_draft",
"table_key_added",
"no_step",
"malformed_proposal",
"port_normalized",
"template_kept_literal",
"step_bypassed",
"trigger_simplified",
"value_clamped",
"human_mail_kept",
"rule_instead_of_ai",
"reply_to_automated"
]
},
"stepId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"nodeType": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"param": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"detail": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "severity", "code", "stepId", "nodeType", "param", "detail" ],
"additionalProperties": false
}
},
"proposedWorkflow": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": {
"type": "integer",
"minimum": 1000,
"maximum": 3600000
}
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name", "params", "onError" ],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
},
"suggestionId": { "type": "string" },
"mailboxId": { "type": "string" },
"firstSeenAt": { "type": "string" },
"lastSeenAt": { "type": "string" },
"status": { "type": "string", "enum": [ "active", "dismissed" ] },
"dismissedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"id",
"groupKey",
"origin",
"volume",
"monthlyVolume",
"windowDays",
"minutesPerEmail",
"minutesPerMonth",
"senders",
"confidence",
"steps",
"prerequisites",
"issues",
"proposedWorkflow",
"suggestionId",
"mailboxId",
"firstSeenAt",
"lastSeenAt",
"status",
"dismissedAt"
],
"additionalProperties": false
}
}
},
"required": [ "suggestions" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
POST /api/v1/analyzer/suggestions/{id}/create
Créer un brouillon depuis une suggestion
Le même geste que créer depuis une opportunité, adressé par suggestion. La suggestion d’un autre membre est le même 404 qu’un identifiant inconnu.
Accès — Session de membre ou clé d’API portant analyzer:write.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
name | string | oui |
createTables | boolean | non |
Même schéma que POST /api/v1/mailboxes/{id}/analyzer/opportunities/{opportunityId}/create.
Réponses
201 — Le nouveau workflow, et les Tables créées avec lui.
| Champ | Type | Requis |
|---|---|---|
workflowId | string | oui |
name | string | oui |
tables | object[] | oui |
Même schéma que POST /api/v1/mailboxes/{id}/analyzer/opportunities/{opportunityId}/create.
400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Cette opération accepte un en-tête Idempotency-Key : rejouer la même requête avec la même clé rend la réponse d’origine au lieu d’agir deux fois. Voir Idempotence.
Codes d’erreur — request.bad_request, analyzer.suggestion_not_found, analyzer.tables_required, analyzer.table_creation_forbidden. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
POST /api/v1/analyzer/suggestions/{id}/dismiss
Rejeter une suggestion
Rend la suggestion telle qu’elle est devenue. Idempotent : un second appel rend la même ligne avec la date du premier rejet.
Accès — Session de membre ou clé d’API portant analyzer:write.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Réponses
200 — La suggestion, rejetée.
| Champ | Type | Requis |
|---|---|---|
suggestion | object | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"suggestion": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1 },
"groupKey": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"origin": {
"oneOf": [
{
"type": "object",
"properties": {
"source": { "type": "string", "const": "model" },
"title": { "type": "string", "minLength": 1 },
"description": { "type": "string" },
"workflowName": { "type": "string", "minLength": 1, "maxLength": 60 },
"benefitRationale": { "type": "string" }
},
"required": [
"source",
"title",
"description",
"workflowName",
"benefitRationale"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"source": { "type": "string", "const": "template" },
"template": {
"type": "string",
"enum": [
"newsletter_cleanup",
"auto_archive_notifications",
"categorize",
"vip_flag",
"draft_reply"
]
},
"params": {
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": { "anyOf": [ { "type": "string" }, { "type": "number" } ] }
},
"fallback": {
"anyOf": [
{
"type": "object",
"properties": {
"reason": {
"type": "string",
"enum": [ "no_answer", "proposal_rejected" ]
},
"llmError": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": {
"type": "string",
"enum": [ "rejected", "adjusted" ]
},
"code": {
"type": "string",
"enum": [
"invalid_shape",
"unknown_node",
"forbidden_node",
"duplicate_step",
"dangling_step",
"invalid_port",
"unknown_param",
"invalid_param",
"unknown_table",
"unknown_column",
"invalid_step",
"sender_not_observed",
"public_domain_sender",
"trigger_too_broad",
"send_forced_to_draft",
"table_key_added",
"no_step",
"malformed_proposal",
"port_normalized",
"template_kept_literal",
"step_bypassed",
"trigger_simplified",
"value_clamped",
"human_mail_kept",
"rule_instead_of_ai",
"reply_to_automated"
]
},
"stepId": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"nodeType": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"param": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
},
"detail": {
"anyOf": [ { "type": "string" }, { "type": "null" } ]
}
},
"required": [
"severity",
"code",
"stepId",
"nodeType",
"param",
"detail"
],
"additionalProperties": false
}
}
},
"required": [ "reason", "llmError", "issues" ],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [ "source", "template", "params", "fallback" ],
"additionalProperties": false
}
]
},
"volume": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"monthlyVolume": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"windowDays": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"minutesPerEmail": { "type": "number", "minimum": 0 },
"minutesPerMonth": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"senders": { "type": "array", "items": { "type": "string" } },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"nodeId": { "type": "string" },
"type": { "type": "string" },
"name": { "type": "string" },
"label": {
"type": "object",
"properties": { "fr": { "type": "string" }, "en": { "type": "string" } },
"required": [ "fr", "en" ],
"additionalProperties": false
},
"effect": { "type": "string", "enum": [ "none", "external_write", "send" ] }
},
"required": [ "nodeId", "type", "name", "label", "effect" ],
"additionalProperties": false
}
},
"prerequisites": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "table" },
"ref": { "type": "string" },
"slug": { "type": "string" },
"name": { "type": "string" },
"columns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Machine key: lowercase, a-z0-9_."
},
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
"type": {
"type": "string",
"enum": [
"text",
"number",
"boolean",
"date",
"datetime",
"select",
"email"
]
},
"isKey": {
"type": "boolean",
"description": "Part of the row key used to find/update a row."
}
},
"required": [ "key", "label", "type", "isKey" ],
"additionalProperties": false
}
}
},
"required": [ "kind", "ref", "slug", "name", "columns" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "connection" },
"connection": { "type": "string" },
"credentialType": { "type": "string" },
"capability": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" }
},
"required": [
"kind",
"connection",
"credentialType",
"capability",
"nodeId",
"nodeType"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "complete" },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" },
"param": { "type": "string" },
"label": {
"type": "object",
"properties": { "fr": { "type": "string" }, "en": { "type": "string" } },
"required": [ "fr", "en" ],
"additionalProperties": false
}
},
"required": [ "kind", "nodeId", "nodeType", "param", "label" ],
"additionalProperties": false
}
]
}
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": { "type": "string", "enum": [ "rejected", "adjusted" ] },
"code": {
"type": "string",
"enum": [
"invalid_shape",
"unknown_node",
"forbidden_node",
"duplicate_step",
"dangling_step",
"invalid_port",
"unknown_param",
"invalid_param",
"unknown_table",
"unknown_column",
"invalid_step",
"sender_not_observed",
"public_domain_sender",
"trigger_too_broad",
"send_forced_to_draft",
"table_key_added",
"no_step",
"malformed_proposal",
"port_normalized",
"template_kept_literal",
"step_bypassed",
"trigger_simplified",
"value_clamped",
"human_mail_kept",
"rule_instead_of_ai",
"reply_to_automated"
]
},
"stepId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"nodeType": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"param": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"detail": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "severity", "code", "stepId", "nodeType", "param", "detail" ],
"additionalProperties": false
}
},
"proposedWorkflow": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name", "params", "onError" ],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
},
"suggestionId": { "type": "string" },
"mailboxId": { "type": "string" },
"firstSeenAt": { "type": "string" },
"lastSeenAt": { "type": "string" },
"status": { "type": "string", "enum": [ "active", "dismissed" ] },
"dismissedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"id",
"groupKey",
"origin",
"volume",
"monthlyVolume",
"windowDays",
"minutesPerEmail",
"minutesPerMonth",
"senders",
"confidence",
"steps",
"prerequisites",
"issues",
"proposedWorkflow",
"suggestionId",
"mailboxId",
"firstSeenAt",
"lastSeenAt",
"status",
"dismissedAt"
],
"additionalProperties": false
}
},
"required": [ "suggestion" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — analyzer.suggestion_not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.