Submit an Item
How to timestamp data by submitting an item on the web form, JSON:API, GraphQL, console WebSocket, CLI, or an MCP agent, with every claims field (name, hash and hash type, description, URL, location, timestamp, metadata), hash mode versus plan-gated claims-only mode, and the limits that apply.
Overview
Submitting an item is how you timestamp something with Truestamp. You describe the data in a small structured object called the claims, Truestamp reduces those claims to a cryptographic fingerprint the moment they arrive (see the item’s composite fingerprint), and from there the item advances toward a portable proof that the data was submitted within a provable submission window (see the proof lifecycle). Your file itself is never uploaded: in the usual mode you submit a hash of the data, so the content stays with you.
At that same instant Truestamp notes which public records already existed, the item’s witnesses, and folds them into the same fingerprint. The block then at the head of Truestamp’s internal chain is always among them, and the newest observation from each public randomness source that has one rides along too. Which witnesses your item names is fixed at submission and can never be chosen afterward; together they open the submitted-after edge of your submission window.
There are two submission modes. In hash mode you supply the hash of an external file together with the algorithm that produced it, and that hash is the data being timestamped. In claims-only mode you omit the hash entirely and the claims content itself (a description, freeform metadata, or both) becomes the data of record; this mode is size-gated by the team owner’s plan.
You can submit an item from six surfaces: the web form, the JSON:API, the GraphQL API, the console WebSocket, the command-line client, and an MCP-connected LLM agent. Every surface lands on the same create pipeline, so the resulting items and their fingerprints are identical no matter which path produced them.
Before you begin
- You must be signed in or hold a credential. Every submission surface is authenticated. The web form needs a signed-in session; the JSON:API, GraphQL, and console surfaces take an API key or an OAuth 2.1 access token; the MCP endpoint is OAuth-only.
- Know which team the item will live in. An item belongs to exactly one team, and you need write access to that team (a viewer role cannot submit). On the web form the item goes into your currently selected team. On the APIs you can name a team explicitly; if you do not, the request falls back to your default team preference or your personal team.
- Pick your mode. For a file or any content you can hash, use hash mode:
hashandhash_typeare co-required, so supply both or neither. To timestamp short self-contained content directly, use claims-only mode: the claims must then include either a description of at least 32 characters or non-empty metadata (a name-only submission is rejected), and the total encoded claims size must fit the team owner’s plan budget, from 256 bytes on Free up to 16 KB on Enterprise (see plans and entitlements). - Know your allowance. Each submission counts against the monthly item allowance of the team’s billing owner, and that allowance is pooled across every team that owner owns, whoever submitted the item. When the allowance is exhausted, submissions are refused until it resets or the plan is upgraded.
The claims fields
The claims object is the data you are timestamping plus your own statements about it. Only name is always required.
| Field | Required | Rules |
|---|---|---|
name |
yes | 1 to 64 characters; letters, numbers, and common punctuation in any language |
hash |
with hash_type |
lowercase hexadecimal, 32 to 128 characters; length must match the chosen algorithm’s output |
hash_type |
with hash |
one of md5, sha1, sha224, sha256, sha384, sha512, sha3_224, sha3_256, sha3_384, sha3_512, blake2s, blake2b |
description |
no | up to 256 characters |
url |
no | HTTPS only, up to 256 characters, must point at a public host (addresses on private or internal networks are rejected) |
location |
no | an object with latitude (-90 to 90) and longitude (-180 to 180), both required together |
timestamp |
no | a flexible ISO 8601 value (2026, 2026-07, 2026-07-15, or a full datetime); must not be in the future |
metadata |
no | a freeform JSON object of your own fields, nested up to 10 levels; its size is capped by the team owner’s plan (none on Free, 1 KB Starter, 4 KB Pro, 16 KB Enterprise) |
Things to know about how claims are handled:
- Text is sanitized and the object is canonicalized. The
nameanddescriptionare Unicode-normalized, stripped of invisible control characters, and trimmed. The whole claims object is then canonicalized with the JSON Canonicalization Scheme so the same claims always produce the same hash. Empty and null fields are dropped, so omitting an optional field and sending it as null are equivalent. The same holds for an optional text field left blank or holding only spaces: after trimming it is empty, and it is dropped exactly as if it had been omitted, so the stored claims and the claims hash always agree. - Claims nest at most 32 levels deep. The claims object itself counts as the first level, and the limit covers every member, including ones Truestamp does not recognize. Deeper claims are refused before anything else about them is checked.
metadatahas its own, tighter limit of 10 levels. - Claims are immutable. Once submitted they can never be edited, because changing them would change the fingerprint. What you can change later is the item’s team, its visibility, and its tags; none of those are part of any hash.
- Your
timestampis a claim, not the guarantee. It is recorded verbatim as your own statement about the data. The provable timing is the submission window: Truestamp proves when the claims were submitted, never when the underlying data was originally created. locationgets a map. A location claim is displayed on the item and public verification pages as an interactive map with a reverse-geocoded place name and links to external map services.- Separate from the claims, a submission may also carry a visibility (
private,team, orpublic; see item visibility) and tags. The APIs accept tags at submission time, and tags can be added or removed on the item afterward.
Steps
On the web
- Sign in and open
https://www.truestamp.com/items/new. - For hash mode, drag a file onto the drop zone or click it to pick one. The file is hashed locally in your browser and is never uploaded; only the resulting hash, the filename, and the algorithm are sent. Files up to 10 GB are supported, with a progress bar for large files and a Cancel button beside it that stops the hash and returns the drop zone. The filename fills the name field if you have not typed one. If you already have a hash, paste it instead and pick its algorithm from the grid (SHA-256 is the default).
- For claims-only mode, skip the hash and write a description of at least 32 characters or add at least one metadata entry.
- Fill in any optional fields: description, URL, your own timestamp, latitude and longitude. If your plan includes a metadata allowance you can add up to 8 metadata key/value pairs (keys are letters and numbers only, values up to 128 characters).
- Choose the visibility. On the Free plan the form always submits with Public visibility and the Private and Team buttons are locked behind an upgrade prompt; on paid plans all three are selectable and Team is preselected. The lock belongs to this form alone: once the item exists you can change its visibility from its page on any plan, and API submissions default to Private on every plan.
- Select Create Item. You are taken to the new item’s page.
Via the JSON:API
Send a JSON:API create request to the items collection:
curl -X POST https://www.truestamp.com/api/json/items \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
"type": "item",
"attributes": {
"claims": {
"name": "quarterly-report.pdf",
"hash": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
"hash_type": "sha256"
},
"visibility": "team",
"tags": ["finance", "q3"]
}
}
}'
Select the team with a tenant header or query parameter carrying the team id; without one the request falls back to your default team preference or your personal team. When visibility is omitted it defaults to private. See the JSON:API surface for authentication, tenancy, and pagination conventions.
Via GraphQL
The GraphQL API exposes the same operation as the createItem mutation, taking the claims as a typed input object alongside optional visibility and tags. The schema documents every field. See the GraphQL surface.
On the console WebSocket
On an authenticated console connection, send an items.create command. The console surface takes a deliberately small payload: name, description, an optional hash with its optional hash_type, and an optional watch flag that auto-subscribes you to the new item’s lifecycle events so you can watch it advance in real time. This is the one surface where hash_type may be left out alongside a hash: send a hash without one and the console assumes sha256.
[null, "1", "console:lobby", "items.create", {
"name": "server-log-2026-07-15",
"hash": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
"hash_type": "sha256",
"watch": true
}]
Omit hash and hash_type to submit in claims-only mode. OAuth-authenticated connections need the console:write scope for this command; API-key connections are not scope-limited. See the console WebSocket for the wire format and stream catalog.
From the terminal
The Truestamp CLI submits items with truestamp create: it hashes a file locally, exactly like the web form’s drop zone, and submits the claim without the file ever leaving your machine.
Through an MCP agent
An LLM agent connected to the MCP server submits items through a confirm-before-write flow: it first calls a preview operation that computes exactly what the create would produce (the resolved team, the cast claims, the effective visibility) without persisting anything, shows you the result, and only submits after you approve. The agent can pick the team by id or by name, or let it default. Submitting requires the mcp:write OAuth scope. Two platform switches sit above that: the agent endpoint as a whole can be taken offline, in which case an agent cannot connect to it at all, and agent-driven item creation can be switched off on its own, which refuses submissions while leaving the agent’s reads working.
Verify
- Open the item’s page (you are taken there automatically after a web submission, and every API response returns the item’s id). Check that the claims render exactly as you intended: the name, the hash and algorithm, and the location map if you claimed one.
- Watch the state. A fresh item starts in the
createdstate and advances toprocessingand thencommittedas blocks are built on a regular cadence; the exact timing is not a fixed guarantee. See the item lifecycle for what each state means. - Once the item is committed and its block has at least one public blockchain commitment, generate the proof and check it end to end with verify a proof. If you kept your original file, re-hash it and confirm the hash matches the one in the claims.
- Programmatic checks work too: fetch the item by id over the JSON:API or GraphQL, or use a console
items.watchsubscription (orwatch: trueat create time) to receive its lifecycle events as they happen.
Troubleshooting
- “You have reached your plan’s monthly item limit.” The team billing owner’s monthly allowance, counted across all the teams they own, is exhausted. It resets with the calendar month in UTC, or the owner can upgrade.
- “You must have write access to the team.” Your role in the selected team is read-only. Switch to a team where you can write, or ask for a write-capable role.
- A name-only submission is rejected. In claims-only mode the claims must include a description of at least 32 characters or non-empty metadata; add one, or supply an external hash instead.
- Claims content exceeds the plan limit. A claims-only submission is bigger than the team owner’s plan budget. Provide an external hash (hash mode has no claims byte budget) or upgrade the team owner’s plan.
- “claims exceed maximum nesting depth of 32 levels”. Some part of the claims object is nested more than 32 levels deep. Flatten it; custom structure belongs in
metadata, which allows 10 levels. - Metadata is refused. Custom metadata requires a plan with a metadata allowance; the Free plan has none, and each paid tier caps its size.
- “Hash length doesn’t match selected algorithm.” The pasted hash’s length disagrees with the chosen algorithm (for example, a 64-character hash is SHA-256 sized, not SHA-512). Fix the hash or the algorithm; the hash must be lowercase hexadecimal.
- The timestamp is rejected. Your
timestampclaim must be a flexible ISO 8601 value and must not be in the future. - The URL is rejected. Only HTTPS URLs are accepted, and the URL must resolve to a public host; loopback, private, and other internal network addresses are refused.
- A rate-limit error. Two caps per minute protect the ingestion pipeline: one on your own account’s submissions and one platform-wide, shared across all users. Both apply however you submit, including through the API, the console and the MCP server. A refusal says how long to wait; wait that long and retry.