Original-file storage
When a markup is created from an uploaded file (image, PDF, or video), MarkUp can keep the original file so it can be downloaded later. Whether originals are kept is controlled by the workspace’s original-file storage policy:
| Policy | Behaviour |
|---|---|
STORE_ALWAYS | Keep the original for every markup created from a file. |
NEVER_STORE | Never keep originals. |
ASK_PER_PROJECT | Decide per markup (the per-project retainOriginal override). |
A workspace that has never set a policy defaults to NEVER_STORE, so originals are not accumulated
until the workspace opts in.
These endpoints are scoped to the API key’s workspace. Organization-scoped keys must pass
?workspaceId=<id>. Reading the policy is always available; changing the policy, archiving
originals, and the storage breakdown require the storage feature to be enabled for the workspace —
contact support to enable it.
Read the current policy
curl "https://api.markup.io/api/v2/workspace/settings" \
-H "Authorization: Bearer <API-KEY-SECRET>" \
-H "Markup-API-Version: 2023-02-22"{
"data": {
"originalFileStoragePolicy": "NEVER_STORE"
}
}Recipe: switch a workspace to NEVER_STORE and archive existing originals
This is the most common migration: stop keeping originals and clear out the ones already stored to
reduce storage. Do it in a single call by combining the policy change with applyToExisting: true.
curl "https://api.markup.io/api/v2/workspace/settings" \
-X PATCH \
-H "Authorization: Bearer <API-KEY-SECRET>" \
-H "Markup-API-Version: 2023-02-22" \
-H "Content-Type: application/json" \
--data '{
"originalFileStoragePolicy": "NEVER_STORE",
"applyToExisting": true
}'{
"data": {
"originalFileStoragePolicy": "NEVER_STORE",
"appliedToExistingCount": 42
}
}appliedToExistingCount is the number of originals queued for archival. applyToExisting only triggers the
bulk archive when the new policy is NEVER_STORE; it is ignored for other policies.
Prefer to change the policy and archive separately? Set the policy first, then call the bulk-archive endpoint:
curl "https://api.markup.io/api/v2/workspace/originals/archive-all" \
-X POST \
-H "Authorization: Bearer <API-KEY-SECRET>" \
-H "Markup-API-Version: 2023-02-22"{
"data": {
"archivedCount": 42
}
}Archiving is irreversible — once an original is archived it is scheduled for deletion from storage and can no longer be downloaded or re-retained.
Verify the result
Use the storage breakdown to confirm the originals bucket has dropped. Values are in bytes.
curl "https://api.markup.io/api/v2/workspace/storage-breakdown" \
-H "Authorization: Bearer <API-KEY-SECRET>" \
-H "Markup-API-Version: 2023-02-22"{
"data": {
"pdfs": 12000000,
"videos": 0,
"images": 3400000,
"attachments": 800000,
"originals": 0,
"total": 16200000
}
}Per-markup override
With ASK_PER_PROJECT (or to keep a single original even under NEVER_STORE), set the override on an
individual markup. This works only while the original is still available; once archived it cannot be re-retained.
curl "https://api.markup.io/api/v2/markups/<MARKUP-ID>/original" \
-X PATCH \
-H "Authorization: Bearer <API-KEY-SECRET>" \
-H "Markup-API-Version: 2023-02-22" \
-H "Content-Type: application/json" \
--data '{ "retainOriginal": true }'The markup response carries retainOriginal (the override) and hasRetainedOriginal (whether a downloadable
original is currently available). Download a retained original with
GET /api/v2/markups/:id/original/download-url, or archive one with DELETE /api/v2/markups/:id/original.