Skip to content

Upload a document

Files never go through the Public API itself: you ask for a presigned POST, send the file straight to object storage, then reference the upload by its id.

All Public API calls below need an office-scope token: see Public API authentication.

Call FileObjectService.Create with an empty body (REST: POST /services.file_object.v1.FileObjectService/Create).

{
"upload": {
"id": "019512f0-0000-7000-8000-000000000001",
"url": "https://…",
"fields": {
"key": "…",
"bucket": "…",
"Policy": "…",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "…",
"X-Amz-Date": "…",
"X-Amz-Signature": "…"
},
"maxSizeInBytes": 52428800
}
}
FieldDescription
idThe upload id, to reference the file later.
urlWhere to send the multipart/form-data POST.
fieldsForm fields to send unchanged. Treat them as opaque: their names may change.
maxSizeInBytesLargest file the upload accepts (50 MiB).

Send one multipart/form-data POST to url: every entry of fields first, unchanged, then the file as the last part, named file.

const form = new FormData();
for (const [name, value] of Object.entries(upload.fields)) {
form.append(name, value);
}
form.append('file', new Blob([pdfBytes], { type: 'application/pdf' }), 'minutes.pdf');
const response = await fetch(upload.url, { method: 'POST', body: form });
if (!response.ok) {
throw new Error(`Upload failed: ${response.status} ${await response.text()}`);
}

Constraints:

  • Size: from 1 byte to maxSizeInBytes (50 MiB). Storage rejects anything else (EntityTooSmall / EntityTooLarge).
  • Validity: the presigned POST expires 5 minutes after it was issued. Request a new one if needed.
  • Retention: an upload that is not attached is deleted after 24 hours.
  • Format: PDF only — checked when you attach it (step 3).
  • From your server: storage refuses cross-origin uploads from third-party web pages, so send the file from your backend.

Call RegisterService.AddMeetingToRegister (REST: POST /services.register.v1.RegisterService/AddMeetingToRegister):

{
"registerKey": "…",
"label": "Annual general meeting 2026",
"date": "2026-06-30",
"documents": [
{ "name": "Minutes", "type": "REGISTER_ITEM_MINUTES", "uploadId": "019512f0-0000-7000-8000-000000000001" },
{ "name": "Attendance sheet", "type": "REGISTER_ITEM_ANNEXE", "uploadId": "019512f0-0000-7000-8000-000000000002" }
]
}

date is optional. documents needs at least one entry, and type is REGISTER_ITEM_MINUTES or REGISTER_ITEM_ANNEXE.

Before attaching, the server checks each upload:

StatusMessageCause
400Uploaded files not found: …The file was never sent, has expired, or the id belongs to another Public API user.
400Uploaded files must be PDF documents: …The content is not a PDF (the file’s bytes are inspected, not its name or declared type).

An uploadId is only usable by the Public API user that created it.