External Data API

Let an outside system, such as a vendor, an ERP or a weighbridge, work with your SmartTables over a secure API: entries, attachments, settings, approval workflows, access and folders. The same rules apply as in the app.

Overview

The vendor gets its own client ID and secret, not a PersivApps user account. It signs in to get a short-lived access token, then calls the API with it. Every call goes through the same logic the app uses: formulas, autofill, auto-numbered fields, approval workflows, notifications, automations and the audit trail all run as if a person had done it.

  • Base URL: your PersivApps API address, for example https://your-host/persivapps/service. Every path below starts with <base URL>/external/v1/. A trailing slash is optional.
  • Every call with sample requests and responses: the API Reference, searchable, with a downloadable Postman collection and PDF.
  • Machine-readable reference: GET <base URL>/external/v1/openapi.json describes every call, for tools such as Postman.
  • Earlier paths: /external/auth/login, /external/smarttables/data/save and /external/smarttables/data/<id>/update (without /v1) still work and behave the same.

What a vendor can and can't do

  • Only what it has permission for. Each vendor is given permissions such as entries:read or smarttables.settings:write. Each call below lists the permission it needs; a token without it gets permission_denied.
  • Only the SmartTables (or folders) its permission covers. Each permission covers all of your organization's SmartTables, chosen ones, or those in chosen folders. Anything outside returns "not found", the same as an ID that doesn't exist. Nothing in another organization is ever reachable.
  • Only its own entries, by default. Updating, deleting, restoring and changing attachments work only on entries the vendor created, unless it is allowed to change any entry.
  • Only these calls. The vendor's token is refused everywhere else in PersivApps, and these calls don't accept a normal user's login. The vendor can't sign in to the app; what it saves shows as created by a dedicated integration user named after it.
  • Users are read only. A vendor with users:read can list users, roles and user attributes, but never create, change or disable users, or see passwords and signatures.
  • Never: custom scripts, automations, changing users or passwords, organizations, or the organization's system administrator account.

GET /external/v1/me lists the vendor's permissions and the SmartTables each one covers.

Authentication

Send the client ID and secret in the body, or as HTTP Basic authentication:

Request
POST <base URL>/external/v1/auth/login
Content-Type: application/json

{
  "client_id": "ext.acme-logistics.1a2b3c4d",
  "client_secret": "your-client-secret"
}
Response 200
{
  "access_token": "pvx_at_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "entries:read entries:write",
  "refresh_token": "pvx_rt_..."
}
  • Send the access token on every call as Authorization: Bearer <access_token>. It lasts 1 hour.
  • To renew, sign in again, or exchange the refresh token at POST <base URL>/external/v1/auth/token with grant_type=refresh_token plus your client ID and secret. Each refresh token works once.
  • scope (optional): a space-separated list of permissions, to get a token with fewer permissions than the vendor has. The response's scope lists what the token can do. Asking only for permissions the vendor doesn't have returns invalid_scope.
  • Limits on your secret. A secret can have an expiry date and can be limited to your servers' IP addresses. If sign-in suddenly returns 401 from a new server, or after a date, ask us to update it.
CallPermissionWhat it does
GET /external/v1/meanyThis client, the permissions of the current token, and the SmartTables each covers

Requests, responses and errors

  • JSON in and out, except file uploads (multipart/form-data) and downloads.
  • Field IDs: entry values are keyed by field ID, the id of each field in the SmartTable's schema (GET /external/v1/smarttables/<id>).
  • Two IDs per entry: smarttable_data_entry_id identifies an entry; smarttable_data_id identifies one row (an observation) of it. Most row calls take the row ID.
  • Paging: lists take page (from 1) and page_size, and return total_count and total_pages.
  • Successful responses have "status": "success".

Errors come back as {"status": "error", "error": "…", "code": "…"}. Program against code; the error text may change.

StatuscodeMeaning
400invalid_requestThe request is missing something or has a wrong value. The message says what.
400 / 403rejectedThe SmartTable's own rules refused it: a validation failed, adding entries is off, or the entry is submitted and locked.
401—The token is missing, expired or invalid, or the sign-in credentials were wrong.
403permission_deniedThe token doesn't have the permission this call needs. details.required_permission names it.
404not_foundIt doesn't exist, isn't covered by the vendor's permission, or (for changes) wasn't created by this vendor.
405method_not_allowedThat method isn't available on this path.
409not_approved, not_deleted, steps_pendingThe SmartTable isn't approved yet; the row to restore isn't deleted; or the user holds an in-progress step (send force to go ahead).
409not_submitted, not_attested, feature_disabled, no_source, sync_lockedOnly a submitted row can be attested; the row isn't attested; entry access control is off on this server; the SmartTable isn't built from a spreadsheet; or it is locked against spreadsheet sync.
429rate_limited or —Too many requests. Wait, then retry.

Sign-in and token errors follow the OAuth 2.0 format instead: {"error": "invalid_client" | "invalid_grant" | "invalid_scope" | "unsupported_grant_type", "error_description": "…"}.

Entries

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/entriesentries:readList entries of a SmartTable (paged; search, filters, sort, created/updated time window)
GET /external/v1/smarttables/data/<smarttable_data_id>entries:readRead one row (an observation of an entry)
GET /external/v1/entries/<smarttable_data_entry_id>entries:readRead an entry with all its observations
DELETE /external/v1/smarttables/data/<smarttable_data_id>entries:deleteDelete a row (soft delete; can be restored)
POST /external/v1/smarttables/data/<smarttable_data_id>/restoreentries:deleteRestore a deleted row
DELETE /external/v1/smarttables/data/<smarttable_data_id>/permanententries:adminDelete a row permanently (cannot be undone)
POST /external/v1/smarttables/data/<smarttable_data_id>/unsubmitentries:adminUnsubmit a submitted row so it can be edited again
POST /external/v1/smarttables/data/<smarttable_data_id>/release-lockentries:adminRelease the edit lock on a row someone left open
POST /external/v1/smarttables/data/saveentries:writeCreate an entry, or a new observation of an entry this client owns
PUT /external/v1/smarttables/data/<smarttable_data_id>/updateentries:writeUpdate fields of a saved row

Create an entry

Request
POST <base URL>/external/v1/smarttables/data/save
Authorization: Bearer pvx_at_...
Content-Type: application/json

{
  "smarttable_id": 61,
  "smarttable_values": { "1": "Truck MH12AB1234", "3": 12.5, "8": "Arrived" },
  "is_submit": false,
  "client_op_id": "acme-dispatch-000123"
}
Response 201
{
  "status": "success",
  "message": "Saved",
  "duplicate": false,
  "smarttable_id": 61,
  "smarttable_data_id": 189862,
  "smarttable_data_entry_id": 195569,
  "observation_number": 1
}
FieldRequiredMeaning
smarttable_idYesThe SmartTable to save into.
smarttable_valuesYesField values keyed by field ID. A table field takes an array, one value per row.
is_submitNotrue submits the entry and starts any approval workflow. The default saves a draft.
client_op_idNo, recommendedYour own unique ID for this save. Sending the same ID again, say after a timeout, returns the original entry (status 200, "duplicate": true) instead of creating a second one.
smarttable_data_entry_idNoAdds a new observation to one of your entries instead of a new entry. Use it with observation_number.
⚠️ Required fields aren't enforced Required fields are checked by the entry form, not by the save itself, as in the app. Make sure your system sends every field the SmartTable needs.

Update an entry

Request
PUT <base URL>/external/v1/smarttables/data/189862/update
Authorization: Bearer pvx_at_...
Content-Type: application/json

{
  "smarttable_values": { "8": "Unloaded" },
  "cleared_fields": ["3"]
}
  • Send only the fields you want to change; the others keep their values.
  • An empty string means "no change", not "clear". To blank a field, list its ID in cleared_fields.
  • is_submit: true submits a draft. A submitted entry can be changed only if the SmartTable's settings allow it.

List entries

  • page_size is 50, 100, 200 or 500 (default 100).
  • search matches any field's value. sort is a field ID or created_at, updated_at, observation_number, entry_id, with dir=asc|desc. submitted=1|0 filters on submitted.
  • filters is a JSON list, for example [{"column_id": "3", "operator": "equals", "value": "Arrived"}]; at most 20.
  • updated_after, updated_before, created_after, created_before limit the list to a time window, as an ISO 8601 date (2026-10-01, midnight UTC) or date-time (2026-10-01T09:30:00+05:30; no offset means UTC). after includes the moment, before excludes it. To fetch only what changed since your last run, send updated_after with the time you last fetched and sort=updated_at&dir=asc.
  • deleted=1 lists deleted rows instead, and needs entries:delete.
  • The SmartTable's own "Show entries" setting applies: on a SmartTable set to show users only their own entries, the vendor sees only the entries it created.

Delete, restore and admin actions

  • Delete is a soft delete; POST …/restore brings the row back.
  • entries:admin deletes permanently (cannot be undone), unsubmits a submitted row, and releases an edit lock someone left open. These aren't limited to the vendor's own entries.

Bulk operations

CallPermissionWhat it does
POST /external/v1/bulk/deleteentries.bulk:deleteDelete many rows (soft delete; can be restored). Body: {"smarttable_data_ids": [...]}
POST /external/v1/bulk/restoreentries.bulk:deleteRestore many deleted rows. Body: {"smarttable_data_ids": [...]}
POST /external/v1/bulk/delete-permanentlyentries.bulk:adminPermanently delete many rows (cannot be undone). Body: {"smarttable_data_ids": [...]}
POST /external/v1/bulk/update-versionentries.bulk:adminMove many rows to the latest approved schema and/or display version. Body: {"smarttable_data_ids": [...], "update": "entry" | "display" | "both"}
POST /external/v1/smarttables/<smarttable_id>/bulk-uploadentries.bulk:writeAdd rows to a relational SmartTable from an Excel file (multipart, key "file"; column headers = field names)
  • Send up to 500 row IDs as {"smarttable_data_ids": [...]}. Each ID is checked on its own: the response lists what was done and, under failed, each ID that wasn't with the reason. An ID the vendor may not use is reported as "Not found".
  • Bulk delete and restore, like single ones, work only on rows the vendor created unless it may change any entry. Permanent delete and the version update (entries.bulk:admin) aren't limited to its own rows.
  • Version update moves rows to the SmartTable's latest approved schema ("update": "entry"), display layout ("display") or both (default). Fields removed from the schema since a row was saved stop showing for it.
  • Excel upload works on relational SmartTables only: multipart/form-data, the workbook under file (.xlsx or .xls, at most 10 MB), first row = field names. Up to 10 uploads per hour per vendor.

Attachments

CallPermissionWhat it does
GET /external/v1/smarttables/data/<smarttable_data_id>/attachmentsentries.attachments:readList a row's attachments
GET /external/v1/smarttables/data/<smarttable_data_id>/attachments/<field_id>/<filename>entries.attachments:readDownload one attachment
POST /external/v1/smarttables/data/<smarttable_data_id>/attachments/<field_id>entries.attachments:writeUpload files to an attachment field (multipart, key "files")
DELETE /external/v1/smarttables/data/<smarttable_data_id>/attachments/<field_id>/<filename>entries.attachments:deleteRemove one attachment
  • Upload with multipart/form-data, each file under the key files, up to 20 per call.
  • Download: the list call returns each file's path; fetch it with GET <base URL>/external/v1/<path>.
  • You can also attach files while creating or updating an entry: send that request as multipart/form-data, smarttable_values as a JSON string, and each file under attachments__<field_id>.
curl
curl -X POST https://your-host/persivapps/service/external/v1/smarttables/data/189862/attachments/6 \
  -H "Authorization: Bearer pvx_at_..." \
  -F files=@weighbridge-slip.pdf

Comments

CallPermissionWhat it does
GET /external/v1/smarttables/data/<smarttable_data_id>/commentsentries.comments:readList a row's comments and notes
POST /external/v1/smarttables/data/<smarttable_data_id>/commentsentries.comments:writeAdd a comment to a row

Comments are plain text, up to 5,000 characters. The list includes notes added in the app.

Approval status

CallPermissionWhat it does
GET /external/v1/entries/<smarttable_data_entry_id>/approvalentries.approvals:readAn entry's approval status, with earlier rounds
GET /external/v1/entries/<smarttable_data_entry_id>/approval/historyentries.approvals:readEarlier approval rounds of an entry (rejected and resubmitted)

Read-only: approvers still approve or reject in the app or from their notification. The status lists each step, who approved it and any comment; signatures are never returned. An entry whose SmartTable has no approval workflow returns "approval_enabled": false.

Attestation and eSign

CallPermissionWhat it does
GET /external/v1/smarttables/data/<smarttable_data_id>/attestationentries.attestation:readA row's attestation and eSign status
POST /external/v1/smarttables/data/<smarttable_data_id>/attestationentries.attestation:writeAttest a row with a signature image; it is recorded as signed by this integration
DELETE /external/v1/smarttables/data/<smarttable_data_id>/attestationentries.attestation:deleteRemove a row's attestation
  • Attest a submitted row with a signature image: multipart/form-data with the file under image, or JSON {"image": "<base64>"}. PNG or JPEG, at most 1 MB.
  • The attestation is recorded as signed by the vendor's integration user, not by a person, and the row's history shows it.
  • eSign (Aadhaar / eMudhra) is read only: the status call returns whether a row's document was e-signed and the transaction ID. Starting an eSign needs a person's own mobile number and OTP, so it can only be done in the app.

Exports

CallPermissionWhat it does
GET /external/v1/entries/<smarttable_data_entry_id>/pdfentries.exports:readDownload an entry's PDF (its display layout)
POST /external/v1/bulk/pdfentries.exports:readDownload many entry PDFs as one zip. Body: {"smarttable_data_entry_ids": [...]} (at most 50)

The PDF is the entry's printed layout. Add include_attachments=false to leave attached PDFs out. Up to 30 PDFs per minute per vendor.

Many at once: POST …/bulk/pdf with {"smarttable_data_entry_ids": [...]} (at most 50) returns one zip. Entries the vendor can't read are left out and listed in the X-Skipped-Entry-Ids response header. Up to 5 zips per 5 minutes per vendor.

SmartTables and schema

CallPermissionWhat it does
GET /external/v1/smarttablessmarttables:readList the SmartTables this client can read
GET /external/v1/smarttables/<smarttable_id>smarttables:readA SmartTable with its current fields (schema)
GET /external/v1/smarttables/<smarttable_id>/versionssmarttables:readA SmartTable's schema versions
POST /external/v1/smarttablessmarttables:writeCreate a SmartTable from a field list (it then waits for approval in the app)
PUT /external/v1/smarttables/<smarttable_id>/schemasmarttables:writeChange a SmartTable's fields (creates a new version)
DELETE /external/v1/smarttables/<smarttable_id>smarttables:deleteDelete a SmartTable
  • A field has the same columns as the schema builder: name, ui_smarttable_element (text, textarea, number, date, month, time, dropdown, multi_select_dropdown, radio_button, button_group, checkbox, attachment), optional, hide, allowed_data, properties and the other columns in the SharePoint column reference.
  • Creating a SmartTable needs smarttables:write on all SmartTables. The new SmartTable waits for approval in the app before entries can be saved.
  • Changing the schema sends the full list of fields. Keep each existing field's id; a field without an id is added. Leaving out an existing field is refused unless you send "allow_remove": true, and changing a field's type unless "allow_type_change": true, because stored values are kept by field ID and would no longer show.
POST /external/v1/smarttables
{
  "name": "Dispatch Log",
  "is_relational": false,
  "fields": [
    { "name": "Truck number", "ui_smarttable_element": "text" },
    { "name": "Weight (t)", "ui_smarttable_element": "number", "optional": true }
  ]
}

Display layouts

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/displaysmarttables.display:readA SmartTable's display (print) layout: the latest approved version, or ?version=N
GET /external/v1/smarttables/<smarttable_id>/display/versionssmarttables.display:readA SmartTable's display layout versions

The display layout is the printed form, as it came from the spreadsheet's display sheet: every cell with its value, style and size, and <pa_…> placeholders where entry values go. Add version=N for an older version, or include_unapproved=1 to include versions not approved yet. Layouts change only through the spreadsheet; to get a filled-in document, download the entry's PDF.

SharePoint and Google Sheets

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/sourcesmarttables.sources:readWhere a SmartTable's schema comes from (SharePoint, Google Sheets or the schema builder)
POST /external/v1/smarttables/<smarttable_id>/syncsmarttables.sources:writeRefresh a SmartTable from its spreadsheet (new versions may need approval in the app)
POST /external/v1/smarttables/from-sourcesmarttables.sources:writeCreate a SmartTable from a SharePoint or Google Sheets file (it then waits for approval in the app)
  • Refresh re-reads the SmartTable's spreadsheet, the same as Refresh in the app. Changed versions may need approval in the app. A SmartTable locked against spreadsheet sync, or built in the schema builder, returns 409.
  • Create takes name, and sharepoint_url or google_sheets_url (an https link on *.sharepoint.com or docs.google.com), plus optional is_relational and observation_count. It needs both smarttables.sources:write and smarttables:write on all SmartTables, and the file must be shared with your organization's PersivApps connection.
  • Up to 20 refreshes and creates per hour per vendor.

Settings

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/settingssmarttables.settings:readA SmartTable's settings
PATCH /external/v1/smarttables/<smarttable_id>/settingssmarttables.settings:writeChange some of a SmartTable's settings (only the keys sent)

PATCH changes only the keys you send:

KeysValues
observation_count1 to 50
submit_button_labelText, up to 50 characters
show_observation_number, show_min_max_values, is_autosave_enabled, autosave_enabled_by_default, enable_attestation, require_submitter_signature, enable_notification_comments, enable_notes, enable_entry_access_control, offline_enabled, compress_attachmentstrue or false
autosave_interval5, 30, 60, 120, 300 or 600 (seconds)
freeze_columns_fields, filter_fields (at most 4), pdf_filename_fieldsLists of field IDs
primary_field_idA field ID, or null
entries_page_size50, 100, 200, 500 or "all"
show_entries, show_entries_attribute_idall, self or attribute (with a user attribute ID)
submit_admin_users, unsubmit_admin_users, attest_users, submit_notification_usersLists of user IDs. submit_admin_users also gives those users access, so it needs access:admin too.

Linking and autofill, fonts, print orientation, who may edit submitted entries and notification buttons can only be changed in the app.

Approval workflow

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/approval-workflowsmarttables.approval:readA SmartTable's approval workflow
PUT /external/v1/smarttables/<smarttable_id>/approval-workflowsmarttables.approval:writeReplace a SmartTable's approval workflow (applies to entries created afterwards)
PUT …/approval-workflow
{
  "enabled": true,
  "steps": [
    { "mode": "any", "approvers": [12, 15], "deadline_days": 2 },
    { "mode": "all", "approvers": [20] }
  ],
  "on_publish": {
    "notify_users": [12],
    "email_users": [30],
    "email": { "subject": "Approved", "body": "Please find the PDF attached.", "signature": "" }
  }
}
  • Steps run in the order sent. mode is any (one approver is enough) or all.
  • Optional: step0 (enabled, notify_on_later_steps, deadline_days), and per step notify_on_later_steps.
  • The new workflow applies to entries created afterwards; entries already in progress keep the workflow they started with.
  • Send {"enabled": false} to turn approvals off.

SmartTable Steps

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/stepssmarttables.steps:readA SmartTable's steps and who is assigned to each
PUT /external/v1/smarttables/<smarttable_id>/stepssmarttables.steps:writeSet who is assigned to each step (steps left out are deactivated)

The steps themselves come from the SmartTable's schema; this sets who is assigned to each. Send {"steps": [{"step_number": 1, "assignees": {"users": [12]}}]}. A step left out is deactivated, not deleted.

Access

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/accessaccess:readWho has access to a SmartTable, and with which role
POST /external/v1/smarttables/<smarttable_id>/accessaccess:adminGive users access to a SmartTable (role: admin, user or viewer)
PUT /external/v1/smarttables/<smarttable_id>/access/<user_id>access:adminChange a user's role on a SmartTable
DELETE /external/v1/smarttables/<smarttable_id>/access/<user_id>access:adminRemove a user's access to a SmartTable
GET /external/v1/access/usersaccess:adminThe organization's users (id, name, username), to give access to
PATCH /external/v1/smarttables/data/<smarttable_data_id>/accessaccess:adminSet who can view, edit or administer one row (overrides the SmartTable default)
GET /external/v1/smarttables/<smarttable_id>/entry-accessaccess:readA SmartTable's entry access rules (who can view, edit and administer its rows)
PUT /external/v1/smarttables/<smarttable_id>/entry-accessaccess:adminSet a SmartTable's entry access rules and switch them on or off (new version)
  • Roles are admin (SmartTable admin), user and viewer.
  • Find user IDs with GET /external/v1/access/users?search=… (or the Users calls below, with users:read).
  • Only active users of your organization can be given access. The organization's system administrator account, and other API clients, can't be changed.
  • Entry-level access (PATCH …/data/<id>/access) overrides who can view, edit or admin one row, each as {"users": [...], "attributes": {...}} or null to go back to the SmartTable's default. It works when entry-level access is turned on.
  • Entry access rules (…/entry-access) are the SmartTable-wide defaults behind the per-row ones. PUT takes "enabled" (true/false) and/or "rules": for view, edit and admin, a rule with any of users, attributes (attribute ID → allowed values), creator_only: true and match_creator_attribute (an attribute ID: same value as the row's creator), or null to clear it. Actions you leave out keep their rule. It saves a new version of the SmartTable's settings, and returns 409 if entry access control is switched off on the server.
PUT …/entry-access
{
  "enabled": true,
  "rules": {
    "view": { "match_creator_attribute": "5" },
    "edit": { "creator_only": true, "users": [12] },
    "admin": null
  }
}

Folders

CallPermissionWhat it does
GET /external/v1/foldersfolders:readList folders
POST /external/v1/foldersfolders:writeCreate a folder (needs folders:write on all folders)
PATCH /external/v1/folders/<folder_id>folders:writeRename a folder
PUT /external/v1/folders/<folder_id>/smarttablesfolders:writeSet a folder's SmartTables (a SmartTable is in at most one folder)
DELETE /external/v1/folders/<folder_id>folders:deleteDelete a folder (its SmartTables are not deleted)
POST /external/v1/folders/<folder_id>/sharefolders:adminShare a folder: users get the 'user' role on its SmartTables
DELETE /external/v1/folders/<folder_id>/share/<user_id>folders:adminUnshare a folder: removes the user's 'user' role on its SmartTables
  • A SmartTable is in at most one folder: adding it to a folder takes it out of any other.
  • Sharing a folder gives its users the user role on the folder's SmartTables; unsharing removes that role again.
  • Creating a folder needs folders:write on all folders.

Users (read only)

CallPermissionWhat it does
GET /external/v1/usersusers:readList the organization's users (paged; search, role, active, attribute filters)
GET /external/v1/users/<user_id>users:readOne user
GET /external/v1/users/<user_id>/smarttablesusers:readThe SmartTables a user has been given access to, and their role on each (only SmartTables this client may read the access of)
GET /external/v1/rolesusers:readThe organization's roles
GET /external/v1/user-attributesusers:readThe organization's user attributes (definitions)
  • users:read is granted for the whole organization, never for chosen SmartTables.
  • A user has user_id, name, username, email, role, active, mfa_enabled, attributes (each with attribute_id, name, value) and timestamps. Passwords, signatures and sign-in data are never returned.
  • List filters: search (name, username or email), role, active=1|0, attribute_id with optional attribute_value. 100 per page.
  • The organization's system administrator account and API clients' integration users aren't listed.
  • …/users/<id>/smarttables lists the user's roles only on SmartTables the vendor's access:read covers.

History

CallPermissionWhat it does
GET /external/v1/smarttables/<smarttable_id>/historyaudit:readA SmartTable's history: versions, approvals, settings changes, bulk uploads
GET /external/v1/smarttables/<smarttable_id>/settings-logaudit:readA SmartTable's settings changes (latest 100)
GET /external/v1/smarttables/data/<smarttable_data_id>/historyaudit:readA row's history: saves, submits, approvals, deletes

The SmartTable history covers versions, approvals, settings changes and bulk uploads. A row's history covers saves, submits, approvals and deletes.

💡 Keep the secret secret Treat the client secret like a password. Store it in the vendor system's secure configuration, never in client-side code or a shared document. If it leaks, contact us to have it replaced.