Verification API
All verification endpoints are public — no authentication required. Base URL: https://auth-api.flowsta.com
GET /api/v1/sign-it/verify
Look up signatures for a file by its SHA-256 hash.
curl "https://auth-api.flowsta.com/api/v1/sign-it/verify?hash=a7f3b9c1e2d4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0"Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
hash | query | string | Yes | SHA-256 hex string (exactly 64 characters) |
Response
{
"signatures": [
{
"file_hash": "a7f3b9c1...",
"signer": "uhCAkynvT4p77x...",
"signer_did": "did:flowsta:z6Mk...",
"signed_at": 1680000000000,
"intent": "Authorship",
"ai_generation": "None",
"content_rights": {
"license": "CCBY",
"commercial_licensing": "OpenToLicensing",
"ai_training": "NotAllowed",
"contact_preference": "AllowContactRequests"
},
"integrity_report": {
"checks_performed": ["PostEofData", "LsbAnalysis", "UnicodeSteg", "MetadataInspection", "EntropyAnalysis", "AppendedFileDetection"],
"issues_found": [],
"checked_at": 1680000000000
},
"perceptual_hash": {
"hash_type": "ImagePHash",
"hash_value": [/* bytes */],
"bands": [/* byte arrays */]
},
"revoked": false,
"revoked_at": null,
"revocation_reason": null,
"contactable": true
}
],
"count": 1
}Rate Limit
30 requests/minute per IP.
POST /api/v1/sign-it/verify-file
Upload a file for server-side perceptual fingerprinting and fuzzy matching. The file is fingerprinted and immediately discarded — not stored.
Supports images (PNG, JPEG, BMP, TIFF, GIF), audio (MP3, WAV, FLAC, OGG), and video (MP4, MKV, AVI, WebM).
curl -X POST "https://auth-api.flowsta.com/api/v1/sign-it/verify-file" \
--data-binary @photo.jpgParameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| body | body | binary | Yes | Raw file bytes. Max 50 MB |
Response
Same format as GET /verify, with additional similarity field (0-100) and match_type: "perceptual". Only returns matches with similarity >= 60%.
Rate Limit
30 requests/minute per IP.
POST /api/v1/sign-it/verify-fuzzy
Fuzzy lookup using pre-computed perceptual hash bands. For when you've already generated the perceptual hash client-side.
curl -X POST "https://auth-api.flowsta.com/api/v1/sign-it/verify-fuzzy" \
-H "Content-Type: application/json" \
-d '{"bands": [[1,2],[3,4],[5,6],[7,8]], "hash_value": [/* full hash bytes */]}'Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
bands | body | number[][] | Yes | LSH band byte arrays |
hash_value | body | number[] | No | Full perceptual hash for Hamming distance |
pixels | body | number[] | No | 72 grayscale pixels (9x8) — server computes gradient hash |
Rate Limit
30 requests/minute per IP.
POST /api/v1/sign-it/sign
Sign a file hash. Requires authentication.
curl -X POST "https://auth-api.flowsta.com/api/v1/sign-it/sign" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <jwt_or_oauth_token>" \
-d '{
"file_hash": "a7f3b9c1e2d4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0",
"intent": "Authorship",
"content_rights": {
"license": "cc-by",
"ai_training": "not_allowed"
}
}'Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
file_hash | body | string | Yes | SHA-256 hex (64 characters) |
intent | body | string | No | Authorship, Approval, Witness, Receipt, Agreement. Default: Authorship |
ai_generation | body | string | No | None, Assisted, Generated |
content_rights | body | object | No | License, AI training policy, etc. |
perceptual_hash | body | object | No | Pre-computed perceptual hash |
Authentication
- JWT session token (from flowsta.com login)
- OAuth access token with
signscope (from third-party apps)
Response
{
"success": true,
"file_hash": "a7f3b9c1...",
"agent_pub_key": "uhCAkynvT4p77x...",
"signed_at": 1680000000000,
"action_hash": "842924c550353c6a..."
}POST /api/v1/sign-it/sign-batch
Sign multiple file hashes in one request. Maximum 100 files per batch.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
files | body | array | Yes | Array of { file_hash, intent?, ai_generation?, content_rights? } |
shared_metadata | body | object | No | Applied to all files unless overridden per-file |
Authentication
Same as /sign.
Response
{
"results": [
{ "file_hash": "a7f3...", "action_hash": "8429...", "success": true },
{ "file_hash": "b8g4...", "action_hash": null, "success": false, "error": "..." }
],
"signed": 1,
"failed": 1
}GET /api/v1/sign-it/my-signatures
Get all signatures created by the authenticated user and their linked agents.
Authentication
- JWT session token, or
- OAuth access token with
verifyscope
Response
{
"signatures": [
{
"file_hash": "a7f3...",
"signed_at": 1680000000000,
"intent": "Authorship",
"action_hash": "8429...",
"revoked": false,
"revoked_at": null,
"revoked_reason": null
}
]
}POST /api/v1/sign-it/revoke
Revoke a signature. Only the original signer can revoke.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
action_hash | body | string | Yes | Hex-encoded action hash of the signature |
reason | body | string | No | Revocation reason (max 280 characters) |
Authentication
JWT session token or OAuth access token with sign scope.
Response
{
"success": true
}POST /api/v1/sign-it/fingerprint
Upload a file so the server computes its perceptual hash with the same algorithm Vault uses — guaranteed matching hashes. Useful when your web app wants to pre-compute a perceptual hash before calling /sign with a perceptual_hash field. The file is immediately discarded after fingerprinting.
Supports images (PNG, JPEG, BMP, TIFF, GIF), audio (MP3, WAV, FLAC, OGG), and video (MP4, MKV, AVI, WebM). Unsupported file types return { "fingerprint": null }.
curl -X POST "https://auth-api.flowsta.com/api/v1/sign-it/fingerprint" \
-H "Authorization: Bearer <jwt_or_oauth_token>" \
--data-binary @photo.jpgParameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| body | body | binary | Yes | Raw file bytes. Max 50 MB |
Authentication
JWT session token or OAuth access token with sign scope.
Response
{
"fingerprint": {
"hash_value": [/* bytes */],
"bands": [[1,2],[3,4],[5,6],[7,8]]
}
}fingerprint is null if the file type is unsupported. The fingerprinter has a 60-second timeout.
POST /api/v1/sign-it/set-thumbnail
Attach a thumbnail to a previously signed entry on the DHT. Only the original signer can set the thumbnail.
curl -X POST "https://auth-api.flowsta.com/api/v1/sign-it/set-thumbnail" \
-H "Authorization: Bearer <jwt_or_oauth_token>" \
-H "Content-Type: application/json" \
-d '{
"action_hash": "842924c550353c6a...",
"thumbnail": "data:image/webp;base64,..."
}'Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
action_hash | body | string | Yes | Hex-encoded action hash of the signature |
thumbnail | body | string | Yes | data:image/... URI, max 15 KB |
Authentication
JWT session token or OAuth access token with sign scope. Must be the original signer.
Response
{
"success": true
}POST /api/v1/sign-it/contact
Send a message to a signer via blind email relay. The signer's email is never exposed.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
signer_agent_key | body | string | Yes | Agent key of the signer |
file_hash | body | string | Yes | File hash the contact is about |
sender_name | body | string | Yes | Your name (max 100 characters) |
sender_email | body | string | Yes | Your email (max 254 characters) |
message | body | string | Yes | Your message (max 500 characters) |
purpose | body | string | No | licensing, ai_training, collaboration, other |
Rate Limit
3 requests/hour per IP.
Response
Always returns success to prevent user enumeration:
{
"success": true,
"message": "Your message has been sent to the signer."
}