Storage contract

A3.Drive gives products a narrow interface for working with files. A product knows only the contract and does not depend on how the storage works inside. A3 products use the same contract as third party systems of the customer, with no internal shortcuts.

The core contract

Four methods, enough for a product to stop storing files of its own. Everything else is an extension over the same data model.

01put(bytes, meta) -> { file_id, version_id }

Bring a file in

Creates the object and its first version. Before creating, it checks content_hash, the hash of the content: a byte identical duplicate is offered as a binding instead of a second object.

02get(file_id, { format, size, version }) -> FileDTO

Fetch a file

Checks permissions, picks the link lifetime by class of operation and issues a short lived signed link. For images it returns the size asked for: thumbnail, medium or full.

03bind(file_id, { product_id, entity_type, entity_id, deep_link, version_pin? }) -> { binding_id }

Bind to an entity

Creates a holder, that is a binding of the file to a product entity: a deal, a ticket, an invoice. The binding points at the existing object instead of copying it. A specific version can be pinned.

04unlink(binding_id, capability_token) -> { ok }

Remove a binding

Removes exactly one binding by its identifier. The call is confirmed with a capability token, a one time signed token for a single operation. There is no separate delete command: an object with no holders goes to cleanup on its own.

One response with file data

A DTO (data transfer object) is the shape of the response with the file fields. The contract defines it once. Products only pass it on and never add fields of their own, otherwise the shared viewer and the shared file picker stop working. The status field is mandatory: without it the interface cannot tell whether to offer editing or view only.

Links in the response are short lived. The application does not keep them for long and simply asks for the file again once a link expires.

{
  "file_id": "b1f0c2e4-...",
  "version_id": "9a77d1c0-...",
  "name": "Regulation.docx",
  "mime": "application/vnd.openxmlformats-...",
  "size_bytes": 84213,
  "status": "signed",
  "permissions": {
    "can_edit": false,
    "can_download": true,
    "can_delete": false
  },
  "download_url": "https://.../signed?exp=...",
  "thumbnail_url": "https://.../thumb?exp=..."
}

Transport headers

Headers tell the storage who calls a method and on whose behalf. The response always comes in the same envelope and the payload sits in the value field. Lists come with a total count, and filters and paging are passed as objects in the query parameters.

Response envelope
{ code, errorCode, success, value }
List
{ items: T[], totalCount }
API_KEY
The calling product key from the integration registry
A3Session
The user session in A3.ID for user scenarios
Domain
The business domain in user scenarios
CompanyId
The company of the domain. It separates the data of organizations and keys quotas and cleanup
ProductId
The product the call is made on behalf of
Language-Code
The language of error texts: RU, EN, KK, KY, MN, UZ. RU by default

Link lifetime

TTL (time to live) is the time during which a signed link opens the file. It equals the duration of the action the link was issued for. This is not a single number in the settings but a policy by class of operation and sensitivity of the file. While a link is valid, revoking permissions does not affect it yet, so the lifetime is kept short.

ClassOrder of magnitudeComment
Display on a pageMinutesOne display of an image or preview. If the link ends up in logs, it is already invalid.
Download on clickTens of minutesEnough for the “opened in a new tab and got distracted” case.
Public linkDays and weeksA deliberate owner policy: expiry, password and revocation.
Signed fileMinimalThe window in which a revocation has not taken effect is kept small on purpose.

Contract extensions

They grow over the same data model. Products connect to the contract as soon as the core is ready and do not wait for the rest of the storage features.

  • list_versionsfreeze_versionVersion history and version freeze
  • set_retentionRetention period during which the object cannot be deleted
  • searchSearch by name and content
  • create_public_linkPublic link with expiry, password and revocation
  • list_holdersList of places where the object is used
  • register_productset_scopeIntegration registration and its permissions
  • Files/MintEditTokenWOPIToken for the online editor. WOPI is the protocol an office editor uses to open a file straight from the storage
  • Sync/ChangesChanges since the last sync, by cursor