Skip to content

SDK Reference

Two SDK packages provide Sign It functionality for different integration patterns:

PackageUse CaseHow It Signs
@flowsta/authWeb apps using OAuthAPI call with OAuth token — server signs via conductor
@flowsta/holochainDesktop Holochain appsIPC call to Flowsta Vault — Vault signs locally

@flowsta/auth — Web App Signing

For web apps that use "Sign in with Flowsta" (OAuth). Requires the sign scope.

hashFile(file)

Hash a file using SHA-256 in the browser via SubtleCrypto. The file is never uploaded.

typescript
import { hashFile } from '@flowsta/auth';

const file = document.querySelector('input[type=file]').files[0];
const hash = await hashFile(file);
// hash = "a7f3b9c1e2d4..." (64 hex characters)
ParameterTypeRequiredDescription
fileFileYesFile object from file input or drag-and-drop

Returns: Promise<string> — hex-encoded SHA-256 hash (64 characters)


signFile(options)

Sign a file hash. The file is never uploaded — only the hash is sent to the API.

typescript
const result = await flowsta.signFile({
  fileHash: hash,
  intent: 'authorship',
  aiGeneration: 'none',
  contentRights: {
    license: 'cc-by',
    aiTraining: 'not_allowed',
    contactPreference: 'allow_contact_requests',
  },
});
console.log('Signed:', result.action_hash);
ParameterTypeRequiredDescription
fileHashstringYesSHA-256 hex string (64 characters)
intentstringNoAuthorship, Approval, Witness, Receipt, Agreement. Default: Authorship
aiGenerationstringNonone, assisted, generated
contentRightsobjectNoSee Content Rights for all fields

Returns:

FieldTypeDescription
successbooleantrue on success
file_hashstringThe hash that was signed
agent_pub_keystringSigner's Holochain agent key (uhCAk... format)
signed_atnumberUnix timestamp in milliseconds
action_hashstring | nullDHT action hash (hex)

Requires: sign scope


signBatch(options)

Sign multiple file hashes in one request. Each file gets its own signature on the DHT.

typescript
const result = await flowsta.signBatch({
  files: [
    { fileHash: hash1 },
    { fileHash: hash2, intent: 'approval' },
  ],
  sharedMetadata: {
    intent: 'authorship',
    aiGeneration: 'none',
    contentRights: { license: 'all-rights-reserved' },
  },
});
console.log(`Signed ${result.signed}, failed ${result.failed}`);
ParameterTypeRequiredDescription
filesarrayYesArray of { fileHash, intent?, aiGeneration?, contentRights? }. Max 100 files
sharedMetadataobjectNoApplied to all files unless overridden per-file

Returns:

FieldTypeDescription
resultsarrayPer-file results: { file_hash, action_hash, success, error? }
signednumberCount of successfully signed files
failednumberCount of failed files

Requires: sign scope


verifyFile(fileHash)

Check if a file has been signed. Public endpoint — no authentication required, but authenticated requests with verify scope get higher rate limits.

typescript
const result = await flowsta.verifyFile(hash);
if (result.count > 0) {
  result.signatures.forEach(sig => {
    console.log(`Signed by ${sig.signer} on ${new Date(sig.signed_at)}`);
    console.log(`License: ${sig.content_rights?.license}`);
  });
}
ParameterTypeRequiredDescription
fileHashstringYesSHA-256 hex string (64 characters)

Returns:

FieldTypeDescription
signaturesarrayArray of signature objects (see Verification API)
countnumberTotal number of signatures

getContentRights(fileHash)

Convenience wrapper over verifyFile() that returns just the content rights info.

typescript
const rights = await flowsta.getContentRights(hash);
if (rights.signed) {
  rights.rights.forEach(r => {
    console.log(`${r.signer}: ${r.license}, AI training: ${r.aiTraining}`);
  });
}

Returns:

FieldTypeDescription
signedbooleanWhether the file has any signatures
signerCountnumberTotal number of signers
rightsarrayArray of { signer, license?, aiTraining?, commercialLicensing?, contactPreference?, aiGeneration? }

@flowsta/holochain — Desktop App Signing

For Holochain apps that run alongside Flowsta Vault. Signs via IPC — the user approves in Vault.

signDocument(options)

Request Vault to sign a file hash. Shows an approval dialog in Vault.

typescript
import { signDocument } from '@flowsta/holochain';

const result = await signDocument({
  clientId: 'flowsta_app_abc123...',
  appName: 'ArtStudio',
  fileHash: 'a7f3b9c1e2d4...',
  label: 'Illustration.png',
  intent: 'authorship',
  contentRights: {
    license: 'cc-by',
    aiTraining: 'not_allowed',
    contactPreference: 'allow_contact_requests',
  },
});
ParameterTypeRequiredDescription
clientIdstringYesYour app's client ID from dev.flowsta.com
appNamestringYesShown in Vault approval dialog
fileHashstringYesSHA-256 hex string (64 characters)
labelstringNoHuman-readable file name for the dialog
intentstringNoauthorship, approval, witness, receipt, agreement
aiGenerationstringNonone, assisted, generated
contentRightsobjectNoSee Content Rights
ipcUrlstringNoDefault: http://127.0.0.1:27777

Returns:

FieldTypeDescription
successbooleantrue if signed
fileHashstringThe hash that was signed
signaturestringBase64 Ed25519 signature
agentPubKeystringSigner's agent key (uhCAk... format)
signedAtstringISO 8601 timestamp
actionHashstring | nullDHT action hash

Errors:

Error ClassWhen
VaultNotFoundErrorVault is not running
VaultLockedErrorVault is locked
UserDeniedErrorUser rejected the signing request
SigningDnaNotInstalledErrorSigning DNA not available in Vault

getSigningStatus(ipcUrl?)

Check if Vault is available for document signing.

typescript
import { getSigningStatus } from '@flowsta/holochain';

const status = await getSigningStatus();
if (status.available) {
  // Show "Sign with Flowsta" button
}

Returns:

FieldTypeDescription
availablebooleantrue if Vault is running, unlocked, and ready to sign
vaultRunningbooleantrue if Vault IPC server is reachable
vaultUnlockedbooleantrue if Vault is unlocked

Content Rights Object

Used by both @flowsta/auth and @flowsta/holochain:

FieldTypeValues
licensestringall-rights-reserved, cc0, cc-by, cc-by-sa, cc-by-nc, cc-by-nc-sa, mit, apache-2, gpl-3
commercialLicensingstringnot_available, open_to_licensing
aiTrainingstringallowed, allowed_with_attribution, requires_license, not_allowed
contactPreferencestringno_contact, allow_contact_requests

All fields are optional. Only declared fields are recorded in the signature.

Documentation licensed under CC BY-SA 4.0.