Upload a document
Uploading a document reserves an immutable, tenant-owned documentId that
you can reference from any number of later job submissions — the bytes
never change once uploaded. Replacing content always means uploading again
and getting back a new id.
Both uploading and retiring a document require the submit scope — the
same scope that submits jobs, since supplying a reusable document is part
of preparing a submission.
Uploading
There is no create/upload/finalize protocol: one multipart/form-data
POST /documents call with a single file field returns a ready id.
import { client, uploadDocument } from '@one-unity/rule-line-sdk';
client.setConfig({
baseUrl: 'https://api.rule-line.example.com',
auth: 'rl_key_your_api_key',
});
const invoiceBytes = new Blob(['%PDF-1.7 ... synthetic invoice bytes ...'], {
type: 'application/pdf',
});
const result = await uploadDocument({ body: { file: invoiceBytes } });
if (result.error) {
throw new Error(`upload failed: ${result.error.code}`);
}
console.log(`uploaded document ${result.data.documentId}`);
The declared media type comes from the Blob's own type — the platform
also detects the actual format from the bytes and refuses a meaningful
mismatch (an XML file declared as a PDF, for example) before the upload
completes.
Equivalent raw HTTP
POST /documents HTTP/1.1
Host: api.rule-line.example.com
Authorization: Bearer rl_key_your_api_key
Content-Type: multipart/form-data; boundary=----ruleLineBoundary
------ruleLineBoundary
Content-Disposition: form-data; name="file"; filename="invoice.pdf"
Content-Type: application/pdf
%PDF-1.7 ... synthetic invoice bytes ...
------ruleLineBoundary--
Expected response
{
"documentId": "33333333-3333-4333-8333-333333333333",
"mediaType": "application/pdf",
"sizeBytes": 41,
"digest": "4f8b2c9a1d6e3f705c8a2b9d1e4f6a3c8b0d2e5f7a9c1b3d6e8f0a2c4b6d8e0f",
"createdAt": "2026-09-14T00:00:00.000Z"
}
documentId is what you pass to Submit a job as
{ "documentId": "..." } inside a role's array — never the raw bytes again.
Retiring a document
Retiring removes a document from future use immediately; runs that already referenced it keep their own governed snapshot regardless. The route takes no request body — only the path parameter identifies which document to retire.
import { client, retireDocument } from '@one-unity/rule-line-sdk';
client.setConfig({
baseUrl: 'https://api.rule-line.example.com',
auth: 'rl_key_your_api_key',
});
const result = await retireDocument({
path: { documentId: '33333333-3333-4333-8333-333333333333' },
});
if (result.error) {
throw new Error(`retire failed: ${result.error.code}`);
}
console.log('document retired');
DELETE /documents/33333333-3333-4333-8333-333333333333 HTTP/1.1
Host: api.rule-line.example.com
Authorization: Bearer rl_key_your_api_key
(no body)
Errors
| Code | When |
|---|---|
DOCUMENT_FILE_MISSING | No file field was present in the multipart body. |
DOCUMENT_UNEXPECTED_FIELD | The upload carried a form field other than file. |
DOCUMENT_MEDIA_TYPE_UNSUPPORTED | The declared media type isn't one the platform accepts. |
DOCUMENT_MEDIA_TYPE_MISMATCH | The declared media type doesn't match the detected bytes. |
DOCUMENT_BYTES_TOO_LARGE | The document exceeds the per-document byte ceiling. |
AUTHENTICATION_REQUIRED / FORBIDDEN | Missing, invalid, or under-scoped credentials. |
See the full POST /documents
and DELETE /documents/{documentId}
references for complete schemas.