Téléverser des relevés bancaires
POST/api/v1/workspaces/:workspace_id/companies/:company_id/bank_statements
Téléverse un ou plusieurs fichiers de relevé dans une entreprise. Un fichier, un relevé : ce 202 répond donc une COLLECTION - une ligne par fichier, dans l'ordre de la requête, chacune avec son propre compte, son propre état et sa propre erreur - et vous interrogez N identifiants plutôt qu'un seul. Un fichier dont l'extraction échoue n'entraîne jamais ses voisins avec lui. Une partie nommant un compte que vous ne pouvez pas atteindre est un cas différent : c'est une requête mal formée, donc le téléversement entier est refusé et rien n'est stocké.
L'extraction transmet le relevé à Mistral AI
En mode extract - celui par défaut lorsque la partie mode est omise - le fichier téléversé est mis à la disposition de Mistral AI, un prestataire OCR tiers, pour y être lu. Énoncez-le à qui téléverse par votre intermédiaire avant qu'il n'envoie un relevé bancaire : ce sont des documents financiers, et la décision de les faire lire par un traitant externe lui revient, en connaissance de cause.
Le parcours, exactement : le traitement d'extraction génère une URL signée et expirante vers le fichier stocké, puis poste cette URL au point de terminaison OCR de Mistral (https://api.mistral.ai/v1/ocr) ; Mistral y va chercher le document et retourne les lignes et les soldes que cette API publie ensuite. L'URL est signée pour 5 minutes, ce qui borne la durée pendant laquelle elle permet d'aller chercher le fichier - cela ne dit rien de ce que le prestataire fait de ce qu'il a déjà lu. Scribee n'énonce ici rien sur la conservation ni sur le lieu de traitement chez Mistral ; si votre propre registre des traitements en a besoin, demandez-les-nous plutôt que de les déduire de cette page.
Deux cas où l'appel n'atteint PAS Mistral. mode=archive stocke le fichier et rien d'autre - aucune extraction n'est mise en file et rien ne sort de la plateforme ; utilisez-le dès que vous voulez de la conservation sans lecture. Et l'extraction par IA est un réglage par entreprise, désactivé tant qu'il n'a pas été activé dans Scribee : lorsqu'il est désactivé, un téléversement en extract est accepté et stocké, aucune extraction ne tourne, et le relevé reste simplement pending - un 202 n'est donc pas à lui seul la preuve que quoi que ce soit ait été envoyé où que ce soit.
Request
Responses
- 202
- 401
- 403
- 404
- 409
- 422
The files were accepted. Each row exists and is yours to poll; none of them has been extracted yet.
Check for meta.unqueued_statement_ids before you start polling. It is absent from the ordinary upload, and present when the statements were stored but one or more extractions could not be started. Those ids will sit at pending with nothing reading them until you re-drive each one with POST /bank_statements/{id}/retry. Retry exactly those: the rest are queued, and re-driving them pays for a second extraction. Do NOT upload the files again - the statements in data already exist, and a fresh upload duplicates them. Replaying this Idempotency-Key is safe and returns this same body with Idempotency-Replayed: true; it creates nothing.
La requête ne porte aucun jeton bearer, ou en porte un qui est invalide ou expiré. doorkeeper_authorize! est le premier contrôle de la chaîne, si bien que la réponse est rendue avant que l'espace de travail, l'entreprise, le drapeau de fonctionnalité et le relevé ne soient résolus - et avant qu'une Idempotency-Key ne soit revendiquée.
Le jeton n'est pas autorisé à effectuer cet appel, et trois contrôles de la chaîne partagée y répondent de manière identique : le SCOPE OAuth déduit du verbe HTTP (celui-ci exige write), l'HABILITATION que l'application détient sur l'espace de travail, et le DRAPEAU DE FONCTIONNALITÉ bank_reconciliation. Le contrôle Pundit propre à l'action en est un quatrième. Les quatre rendent le même corps, message est donc le seul élément qui les distingue ; dans tous les cas, rien n'a été effectué. L'exemple ci-dessous est refusé sur le scope.
No company with this id exists in the workspace named in the path, so nothing was stored. A company belonging to ANOTHER workspace answers the same way - even when your token also holds a grant for that one - so the response cannot be used to probe for a company. Resolved before the action runs, which is why it precedes every refusal above, the Idempotency-Key ones included: a key spent on this call is not claimed.
The Idempotency-Key was already used for a DIFFERENT upload - idempotency_key_reuse. Nothing was stored by this call. Send a fresh key for a new upload, or resend the ORIGINAL files under the same key to replay the stored 202.
The same status carries idempotency_request_in_progress for a different situation: the key is claimed and its outcome is not replayable. That is USUALLY a first call still running, but it is also what you get when a first call completed its effect and then failed while rendering its response - so it does NOT mean nothing happened, and the two cases are not distinguishable from the outside today. Do not retry in a loop. List the company's statements and see what the first call actually created before doing anything else; re-uploading would duplicate whatever it did. The key frees itself 24 hours after first receipt.
The upload was refused and details names the field. file when no part carried one, or when a part sent it as a text value, an object or a list instead of an uploaded file part, mode when the parts disagreed about it - one upload is one batch - or when a part sent it as something other than a mode name, the empty value included: mode= is refused rather than read as the default, because defaulting it would start an extraction nobody asked for. bank_account when a part named an account this company cannot reach. Nothing was stored in any of those cases.
Every refusal on this operation is validation_failed, and none of them stored anything - a 422 here always means the upload was rejected whole, so fix the named field and send it again, with the same Idempotency-Key if you like.
A partial enqueue is NOT one of these. The files are accepted and stored, so it answers 202 with the collection and a meta.unqueued_statement_ids naming the rows whose extraction could not be started - see the 202 above.