Skip to content

Latest commit

 

History

History
983 lines (805 loc) · 83.7 KB

File metadata and controls

983 lines (805 loc) · 83.7 KB

Assinafy Ruby SDK API Reference

Contract source: Assinafy API v1 OpenAPI 3.1.0, retrieved 2026-10-07 from https://api.assinafy.com.br/v1/docs/openapi.json (81 paths, 106 operations, 44 schemas). scripts/check_api_contract.rb validates contract compatibility weekly.

This is the SDK-facing contract reference. Paths below are wire paths; Ruby methods return the unwrapped data member for Assinafy response envelopes, pagination helpers return { data:, meta: }, binary methods return bytes, and documented no-data operations return nil.

Required parameters and object properties are marked with *.

Authentication and safety

  • X-Api-Key is the recommended server-side credential. A bearer token is either a login session token or an OAuth 2.1 access token. If both an API key and a token are configured, the current SDK sends only X-Api-Key; prefer configuring exactly one credential.
  • OAuth 2.1 authenticates an application acting in a user's workspace with that user's permission, as opposed to X-Api-Key/bearer, which authenticate the workspace or user directly. The flow is authorization-code with mandatory PKCE S256; Assinafy::OAuth builds the verifier, challenge, state, and authorization URL, and client.oauth covers the token lifecycle. A token is scoped to one workspace and carries only the scopes the user approved, and it never reaches billing, account lifecycle, credential management, or admin surfaces regardless of scope. A missing scope answers 403 with a WWW-Authenticate challenge naming it, which the SDK exposes as ApiError#context[:www_authenticate] on every resource: reconnect with that scope added rather than retrying. Store the code_verifier, state, and expected issuer with each authorization attempt — the issuer of the authorization server it uses: https://auth.assinafy.com.br in production, https://auth-sandbox.assinafy.com.br in the sandbox. Check state and iss against those stored values on the callback before anything else, including an error= return, and keep refresh tokens out of logs.
  • Signer-facing operations use the one-time signer-access-code query parameter where shown. Never log, commit, or place API keys, bearer tokens, signer codes, or real recipient addresses in examples or fixtures.
  • POST /v1/login answers with an mfa_token challenge instead of an access token when the user has two-factor authentication enabled. AuthResource#verify_mfa exchanges it, without workspace credentials; the challenge is single-use and expires 5 minutes after login.
  • Webhook endpoint signing secrets (whsec_...) are readable and rotatable only with an API key or a user session token, never by OAuth applications. Treat them like API keys. Verify every delivery with WebhookVerifier#verify_delivery against the raw request body.
  • HTTP connections require TLS 1.2 or newer and use Ruby/Faraday TLS verification and the host system trust store; the SDK does not pin the upstream TLS certificate.
  • DocumentResource#verify reports Assinafy upstream verification data. It does not independently validate a PDF signature, certificate chain, OCSP/CRL status, or legal validity. The API artifact name certificated is not an additional local guarantee.

API operations

Method Path Ruby SDK method Authentication Parameters Request body Success wire response
GET /.well-known/oauth-protected-resource OAuthResource#protected_resource_metadata Public None None 200 application/json bare RFC 9728 metadata object { resource: string; authorization_servers: Array; scopes_supported: Array; bearer_methods_supported: Array } — not enveloped
GET /v1/accounts AccountResource#list Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: Array<Account> }
POST /v1/accounts AccountResource#create Bearer token or X-Api-Key None required; application/json object { name*: string; notification_sender_type: string } 200 application/json Envelope plus object { data: Account }
GET /v1/accounts/{accountId} AccountResource#get Bearer token or X-Api-Key path accountId*: string None 200 application/json Envelope plus object { data: Account }
PUT /v1/accounts/{accountId} AccountResource#update Bearer token or X-Api-Key path accountId*: string required; application/json object { name: string; notification_sender_type: string } 200 application/json Envelope plus object { data: Account }
DELETE /v1/accounts/{accountId} AccountResource#delete Bearer token or X-Api-Key path accountId*: string optional; application/json object { force: boolean } 200 application/json Envelope plus object { data: Array }
GET /v1/accounts/{accountId}/documents DocumentResource#list Bearer token or X-Api-Key path accountId*: string
query status: string
query method: string
query search: string
query tags: string
query sort: string
query page: integer
query per-page: integer
None 200 application/json Envelope plus object { data: Array<Document> }
POST /v1/accounts/{accountId}/documents DocumentResource#upload Bearer token or X-Api-Key path accountId*: string required; multipart/form-data object { file*: string (binary) } 200 application/json Envelope plus object { data: Document }
GET /v1/accounts/{accountId}/documents/search DocumentResource#search Bearer token or X-Api-Key path accountId*: string
query search: string
query status: string
query page: integer
query per-page: integer
None 200 application/json Envelope plus object { data: Array<Document> }
GET /v1/accounts/{accountId}/documents/{documentId}/tags DocumentResource#list_tags Bearer token or X-Api-Key path accountId*: string
path documentId*: string
None 200 application/json Envelope plus object { data: Array<Tag> }
PUT /v1/accounts/{accountId}/documents/{documentId}/tags DocumentResource#replace_tags Bearer token or X-Api-Key path accountId*: string
path documentId*: string
required; application/json object { tags: Array } 200 application/json Envelope plus object { data: Array<Tag> }
POST /v1/accounts/{accountId}/documents/{documentId}/tags DocumentResource#append_tags Bearer token or X-Api-Key path accountId*: string
path documentId*: string
required; application/json object { tags: Array } 200 application/json Envelope plus object { data: Array<Tag> }
DELETE /v1/accounts/{accountId}/documents/{documentId}/tags/{tagId} DocumentResource#detach_tag Bearer token or X-Api-Key path accountId*: string
path documentId*: string
path tagId*: string
None 200 application/json Envelope plus object { data: object { detached: boolean } }
GET /v1/accounts/{accountId}/fields FieldResource#list Bearer token or X-Api-Key path accountId*: string
query include_inactive: boolean
query include_standard: boolean
None 200 application/json Envelope plus object { data: Array<Field> }
POST /v1/accounts/{accountId}/fields FieldResource#create Bearer token or X-Api-Key path accountId*: string required; application/json object { name*: string; type*: string; regex: string; is_required: boolean } 200 application/json Envelope plus object { data: Field }
POST /v1/accounts/{accountId}/fields/validate-multiple FieldResource#validate_multiple Bearer token or X-Api-Key path accountId*: string required; application/json Array<object { field_id*: string; value*: any JSON value }> 200 application/json Envelope plus object { data: Array<FieldValidationResult> }
GET /v1/accounts/{accountId}/fields/{fieldId} FieldResource#get Bearer token or X-Api-Key path accountId*: string
path fieldId*: string
None 200 application/json Envelope plus object { data: Field }
PUT /v1/accounts/{accountId}/fields/{fieldId} FieldResource#update Bearer token or X-Api-Key path accountId*: string
path fieldId*: string
required; application/json object { name: string; regex: string; is_active: boolean } 200 application/json Envelope plus object { data: Field }
DELETE /v1/accounts/{accountId}/fields/{fieldId} FieldResource#delete Bearer token or X-Api-Key path accountId*: string
path fieldId*: string
None 200 application/json Envelope plus object { data: Array }
POST /v1/accounts/{accountId}/fields/{fieldId}/validate FieldResource#validate Bearer token or X-Api-Key path accountId*: string
path fieldId*: string
required; application/json object { value*: any JSON value } 200 application/json Envelope plus object { data: FieldValidation }
GET /v1/accounts/{accountId}/logo AccountResource#download_logo Bearer token or X-Api-Key path accountId*: string None 200 image/* string (binary)
POST /v1/accounts/{accountId}/logo AccountResource#upload_logo Bearer token or X-Api-Key path accountId*: string required; multipart/form-data object { file*: string (binary) } 200 application/json Envelope
DELETE /v1/accounts/{accountId}/logo AccountResource#delete_logo Bearer token or X-Api-Key path accountId*: string None 200 application/json Envelope
GET /v1/accounts/{accountId}/signers SignerResource#list Bearer token or X-Api-Key path accountId*: string
query search: string
query page: integer
query per-page: integer
None 200 application/json Envelope plus object { data: Array<Signer> }
POST /v1/accounts/{accountId}/signers SignerResource#create Bearer token or X-Api-Key path accountId*: string required; application/json object { full_name*: string; email: string (email); whatsapp_phone_number: string; government_id: string (CPF or CNPJ; required for DigitalCertificate signers) } 200 application/json Envelope plus object { data: Signer }
GET /v1/accounts/{accountId}/signers/{signerId} SignerResource#get Bearer token or X-Api-Key path accountId*: string
path signerId*: string
None 200 application/json Envelope plus object { data: Signer }
PUT /v1/accounts/{accountId}/signers/{signerId} SignerResource#update Bearer token or X-Api-Key path accountId*: string
path signerId*: string
required; application/json object { full_name: string; email: string (email); whatsapp_phone_number: string; government_id: string } 200 application/json Envelope plus object { data: Signer }
DELETE /v1/accounts/{accountId}/signers/{signerId} SignerResource#delete Bearer token or X-Api-Key path accountId*: string
path signerId*: string
None 200 application/json Envelope plus object { data: Array }
GET /v1/accounts/{accountId}/stats AccountResource#stats Bearer token or X-Api-Key path accountId*: string
query granularity: string
query month: string
None 200 application/json Envelope plus object { data: Array<DocumentStatsRow> }
GET /v1/accounts/{accountId}/tags TagResource#list Bearer token or X-Api-Key path accountId*: string
query search: string
None 200 application/json Envelope plus object { data: Array<Tag> }
POST /v1/accounts/{accountId}/tags TagResource#create Bearer token or X-Api-Key path accountId*: string required; application/json object { name*: string; color: string } 200 application/json Envelope plus object { data: Tag }
PUT /v1/accounts/{accountId}/tags/{tagId} TagResource#update Bearer token or X-Api-Key path accountId*: string
path tagId*: string
required; application/json object { name: string; color: string } 200 application/json Envelope plus object { data: Tag }
DELETE /v1/accounts/{accountId}/tags/{tagId} TagResource#delete Bearer token or X-Api-Key path accountId*: string
path tagId*: string
query force: boolean
None 200 application/json Envelope plus object { data: object { deleted: boolean } }
GET /v1/accounts/{accountId}/templates TemplateResource#list Bearer token or X-Api-Key path accountId*: string
query search: string
query page: integer
query per-page: integer
None 200 application/json Envelope plus object { data: Array<Template> }
POST /v1/accounts/{accountId}/templates/{templateId}/documents DocumentResource#create_from_template Bearer token or X-Api-Key path accountId*: string
path templateId*: string
required; application/json object { signers*: Array<object { role_id*: string; id*: string; verification_method: string; notification_methods: Array; step: integer }>; editor_fields: Array<object { field_id*: string; value*: string }>; name: string; message: string; expires_at: string (date-time); tags: Array } 200 application/json Envelope plus object { data: Document }
POST /v1/accounts/{accountId}/templates/{templateId}/documents/estimate-cost DocumentResource#estimate_cost_from_template Bearer token or X-Api-Key path accountId*: string
path templateId*: string
required; application/json object { signers*: Array<object { role_id*: string; verification_method: string; notification_methods: Array }> } 200 application/json Envelope plus object { data: CostEstimate }
GET /v1/accounts/{accountId}/theme AccountResource#theme Bearer token or X-Api-Key path accountId*: string None 200 application/json Envelope plus object { data: AccountTheme }
GET /v1/accounts/{accountId}/webhooks WebhookResource#list_dispatches Bearer token or X-Api-Key path accountId*: string
query endpoint_id: string
query event: string
query delivered: string
query from: integer
query to: integer
query page: integer
query per-page: integer
None 200 application/json Envelope plus object { data: Array<WebhookDispatch> }
GET /v1/accounts/{accountId}/webhooks/endpoints WebhookResource#list_endpoints Bearer token or X-Api-Key; OAuth account:read path accountId*: string None 200 application/json Envelope plus object { data: Array<WebhookEndpoint> }
POST /v1/accounts/{accountId}/webhooks/endpoints WebhookResource#create_endpoint Bearer token or X-Api-Key; OAuth webhooks:write path accountId*: string required; application/json object { url*: string (uri); email*: string (email); events*: Array; name: string; is_active: boolean; signing_enabled: boolean }; unknown keys raise ValidationError locally 200 application/json Envelope plus object { data: WebhookEndpoint }; 400 duplicate URL, 403 past the plan limit (1 endpoint, 3 on paid plans)
GET /v1/accounts/{accountId}/webhooks/endpoints/{endpointId} WebhookResource#get_endpoint Bearer token or X-Api-Key; OAuth account:read path accountId*: string
path endpointId*: string
None 200 application/json Envelope plus object { data: WebhookEndpoint }
PUT /v1/accounts/{accountId}/webhooks/endpoints/{endpointId} WebhookResource#update_endpoint Bearer token or X-Api-Key; OAuth webhooks:write path accountId*: string
path endpointId*: string
required; application/json object { url: string (uri); email: string (email); events: Array; name: string; is_active: boolean; signing_enabled: boolean } — partial; at least one field 200 application/json Envelope plus object { data: WebhookEndpoint }
DELETE /v1/accounts/{accountId}/webhooks/endpoints/{endpointId} WebhookResource#delete_endpoint Bearer token or X-Api-Key; OAuth webhooks:write path accountId*: string
path endpointId*: string
None 200 application/json Envelope; SDK returns nil
GET /v1/accounts/{accountId}/webhooks/endpoints/{endpointId}/secret WebhookResource#endpoint_secret Bearer token or X-Api-Key; not available to OAuth applications path accountId*: string
path endpointId*: string
None 200 application/json Envelope plus object { data: WebhookEndpointSecret }; 400 when signing is disabled
POST /v1/accounts/{accountId}/webhooks/endpoints/{endpointId}/secret/rotate WebhookResource#rotate_endpoint_secret Bearer token or X-Api-Key; not available to OAuth applications path accountId*: string
path endpointId*: string
None 200 application/json Envelope plus object { data: WebhookEndpointSecret } (the new secret; the old one stops working immediately)
PUT /v1/accounts/{accountId}/webhooks/inactivate WebhookResource#inactivate Bearer token or X-Api-Key path accountId*: string None; acts on the account's oldest endpoint 200 application/json Envelope plus object { data: WebhookSubscription }
GET /v1/accounts/{accountId}/webhooks/subscriptions WebhookResource#get Bearer token or X-Api-Key path accountId*: string None; reads the account's oldest endpoint; SDK returns nil on 404 200 application/json Envelope plus object { data: WebhookSubscription }
PUT /v1/accounts/{accountId}/webhooks/subscriptions WebhookResource#register Bearer token or X-Api-Key path accountId*: string required; application/json object { events*: Array; is_active*: boolean; url*: string (uri); email*: string (email) } — creates or replaces the account's oldest endpoint; the SDK defaults is_active to true and rejects other keys 200 application/json Envelope plus object { data: WebhookSubscription }
POST /v1/accounts/{accountId}/webhooks/{historyId}/retry WebhookResource#retry_dispatch Bearer token or X-Api-Key path accountId*: string
path historyId*: string
None 200 application/json Envelope plus object { data: WebhookDispatch }
GET /v1/assignments AssignmentResource#list Bearer token or X-Api-Key query page: integer
query per-page: integer
None 200 application/json Envelope plus object { data: Array<Assignment> }
POST /v1/auth/link-social-login AuthResource#link_social_login Bearer token or X-Api-Key None required; application/json object { provider*: string; token*: string } 200 application/json Envelope
PUT /v1/authentication/change-password AuthResource#change_password Bearer token or X-Api-Key None required; application/json object { email*: string (email); password*: string (password); new_password*: string (password) } 200 application/json Envelope plus object { data: object { email: string (email) } }
POST /v1/authentication/mfa/verify AuthResource#verify_mfa Public None required; application/json object { mfa_token*: string; code*: string (6-digit authenticator code or recovery code) } 200 application/json Envelope plus object { data: AuthSession }; 400 invalid code, 401 expired, used, or over-attempted challenge
PUT /v1/authentication/request-password-reset AuthResource#request_password_reset Public None required; application/json object { email*: string (email) } 200 application/json Envelope plus object { data: object { email: string (email) } }
PUT /v1/authentication/reset-password AuthResource#reset_password Public None required; application/json object { email*: string (email); token: string; new_password*: string (password) } 200 application/json Envelope plus object { data: object { email: string (email) } }
POST /v1/authentication/social-login AuthResource#social_login Public None required; application/json object { provider*: string; token*: string; has_accepted_terms*: boolean } 200 application/json Envelope plus object { data: AuthSession }
GET /v1/documents/statuses DocumentResource#statuses Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: Array<DocumentStatus> }
GET /v1/documents/{documentId} DocumentResource#details Bearer token or X-Api-Key path documentId*: string None 200 application/json Envelope plus object { data: Document }
DELETE /v1/documents/{documentId} DocumentResource#delete Bearer token or X-Api-Key path documentId*: string None 200 application/json Envelope plus object { data: Array }
PATCH /v1/documents/{documentId} DocumentResource#rename Bearer token or X-Api-Key path documentId*: string required; application/json object { name*: string } 200 application/json Envelope plus object { data: Document }
GET /v1/documents/{documentId}/activities DocumentResource#activities Bearer token or X-Api-Key path documentId*: string None 200 application/json Envelope plus object { data: Array<DocumentActivity> }
POST /v1/documents/{documentId}/assignments AssignmentResource#create Bearer token or X-Api-Key path documentId*: string required; application/json object { method*: string; signers*: Array<object { id*: string; verification_method: string; notification_methods: Array; step: integer }>; entries: Array<object { page_id: string; fields: Array<object { signer_id: string; field_id: string; display_settings: DisplaySettings }> }>; message: string; expires_at: string (date-time); copy_receivers: Array } 200 application/json Envelope plus object { data: Assignment }
POST /v1/documents/{documentId}/assignments/estimate-cost AssignmentResource#estimate_cost Bearer token or X-Api-Key path documentId*: string required; application/json object { method: string; signers: Array<object { verification_method: string; notification_methods: Array }>; entries: Array } 200 application/json Envelope plus object { data: CostEstimate }
POST /v1/documents/{documentId}/assignments/{assignmentId} AssignmentResource#sign signer-access-code query parameter path documentId*: string
path assignmentId*: string
required; application/json Array<object { itemId*: string; fieldId*: string; pageId*: string; value*: string }> 200 application/json Envelope plus object { data: object }
PUT /v1/documents/{documentId}/assignments/{assignmentId}/reject AssignmentResource#decline signer-access-code query parameter path documentId*: string
path assignmentId*: string
required; application/json object { decline_reason*: string } 200 application/json Envelope plus object { data: Array }
PUT /v1/documents/{documentId}/assignments/{assignmentId}/reset-expiration AssignmentResource#reset_expiration Bearer token or X-Api-Key path documentId*: string
path assignmentId*: string
required; application/json object { expires_at: string (date-time) } 200 application/json Envelope plus object { data: Assignment }
POST /v1/documents/{documentId}/assignments/{assignmentId}/signers/{signerId}/estimate-resend-cost AssignmentResource#estimate_resend_cost Bearer token or X-Api-Key path documentId*: string
path assignmentId*: string
path signerId*: string
None 200 application/json Envelope plus object { data: CostEstimate }
PUT /v1/documents/{documentId}/assignments/{assignmentId}/signers/{signerId}/resend AssignmentResource#resend_notification Bearer token or X-Api-Key path documentId*: string
path assignmentId*: string
path signerId*: string
None 200 application/json Envelope plus object { data: object { is_sent: boolean; document_id: string; signer_id: string } }
GET /v1/documents/{documentId}/assignments/{assignmentId}/whatsapp-notifications AssignmentResource#whatsapp_notifications Bearer token or X-Api-Key path documentId*: string
path assignmentId*: string
None 200 application/json Envelope plus object { data: Array<WhatsappNotification> }
GET /v1/documents/{documentId}/download/{artifactName} DocumentResource#download Bearer token or X-Api-Key path documentId*: string
path artifactName*: string
None 200 application/pdf string (binary)
GET /v1/documents/{documentId}/pages/{pageId}/download DocumentResource#download_page Bearer token or X-Api-Key path documentId*: string
path pageId*: string
None 200 image/* string (binary)
PUT /v1/documents/{documentId}/signers/confirm-data SignerResource#confirm_data signer-access-code query parameter path documentId*: string required; application/json object { full_name: string; email: string (email); government_id: string } 200 application/json Envelope plus object { data: Signer }
GET /v1/documents/{documentId}/thumbnail DocumentResource#thumbnail Bearer token or X-Api-Key path documentId*: string None 200 image/* string (binary)
GET /v1/documents/{documentSignatureHash}/verify DocumentResource#verify Public path documentSignatureHash*: string None 200 application/json Envelope plus object { data: DocumentVerification }
GET /v1/field-types FieldResource#types Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: Array<FieldType> }
POST /v1/login AuthResource#login Public None required; application/json object { email*: string (email); password*: string (password) } 200 application/json Envelope plus object { data: AuthSession }, or object { mfa_token: string } when two-factor authentication is enabled — complete it with POST /v1/authentication/mfa/verify
POST /v1/oauth/token OAuthResource#token, #exchange_code, #refresh Public (client authenticates with client_id in the body) None required; application/x-www-form-urlencoded (RFC 6749; also accepts application/json) object { grant_type*: string enum authorization_code, refresh_token, urn:ietf:params:oauth:grant-type:token-exchange; client_id*: string; code: string; redirect_uri: string (uri); code_verifier: string; refresh_token: string; client_secret: string; resource: string (uri); subject_token: string; subject_token_type: string; requested_token_type: string } 200 application/json flat object { access_token: string; token_type: string; expires_in: integer; refresh_token: string (nullable); scope: string; id_token: string (nullable); issued_token_type: string (token exchange only) } — not enveloped
POST /v1/oauth/revoke OAuthResource#revoke Public (client authenticates with client_id in the body) None required; application/x-www-form-urlencoded (RFC 7009; also accepts application/json) object { token*: string; client_id*: string; token_type_hint: string enum access_token, refresh_token; client_secret: string } 200 empty body — every token outcome reports success
GET /v1/oauth/userinfo OAuthResource#userinfo Bearer token or X-Api-Key; requires the openid scope None None 200 application/json flat object { sub: string; name: string (nullable); email: string (email, nullable); email_verified: boolean (nullable) } — not enveloped
GET /v1/public/documents/{documentId} DocumentResource#public_info Public path documentId*: string None 200 application/json Envelope plus object { data: Document }
PUT /v1/public/documents/{documentId}/send-token DocumentResource#send_token Public path documentId*: string optional; application/json object { email: string (email) } 200 application/json Envelope
GET /v1/sign AssignmentResource#signer_document signer-access-code query parameter query has_accepted_terms: boolean None 200 application/json Envelope plus object { data: Document }
POST /v1/signature SignerResource#upload_signature signer-access-code query parameter query type: string
query reuse: boolean
required; image/png string (binary) 200 application/json Envelope
GET /v1/signature/{signatureType} SignerResource#download_signature signer-access-code query parameter path signatureType*: string None 200 image/* string (binary)
PUT /v1/signers/accept-terms SignerResource#accept_terms signer-access-code query parameter None None 200 application/json Envelope
PUT /v1/signers/documents/decline-multiple SignerDocumentResource#decline_multiple signer-access-code query parameter None required; application/json object { document_ids*: Array; decline_reason*: string } 200 application/json Envelope plus object { data: Array }
PUT /v1/signers/documents/sign-multiple SignerDocumentResource#sign_multiple signer-access-code query parameter None required; application/json object { document_ids*: Array } 200 application/json Envelope plus object { data: Array }
GET /v1/signers/self SignerResource#self_data signer-access-code query parameter None None 200 application/json Envelope plus object { data: SignerSelf }
GET /v1/signers/{signerId}/document SignerDocumentResource#current signer-access-code query parameter path signerId*: string None 200 application/json Envelope plus object { data: Document }
GET /v1/signers/{signerId}/documents SignerDocumentResource#list signer-access-code query parameter path signerId*: string
query page: integer
query per-page: integer
None 200 application/json Envelope plus object { data: Array<Document> }
GET /v1/signers/{signerId}/documents/search SignerDocumentResource#search signer-access-code query parameter path signerId*: string
query search: string
None 200 application/json Envelope plus object { data: Array<Document> }
GET /v1/signers/{signerId}/documents/{documentId}/download/{artifactName} SignerDocumentResource#download Public path signerId*: string
path documentId*: string
path artifactName*: string
None 200 application/pdf string (binary)
GET /v1/users/api-keys AuthResource#get_api_key Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: ApiKey }
POST /v1/users/api-keys AuthResource#create_api_key Bearer token or X-Api-Key None required; application/json object { password*: string (password) } 200 application/json Envelope plus object { data: ApiKey }
DELETE /v1/users/api-keys AuthResource#delete_api_key Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: Array }
GET /v1/users/self UserResource#me Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: AuthUser }
GET /v1/users/self/mfa AuthResource#mfa_methods Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: object { methods: Array<object { id: string; type: string; label: string; confirmed_at: string (date-time); last_used_at: string (date-time) }>; recovery_codes_remaining: integer } }
POST /v1/users/self/mfa/totp AuthResource#start_totp_enrollment Bearer token or X-Api-Key None optional; application/json object { label: string } 200 application/json Envelope plus object { data: object { id: string; secret: string (returned only here); provisioning_uri: string } }
PUT /v1/users/self/mfa/totp/confirm AuthResource#confirm_totp_enrollment Bearer token or X-Api-Key None required; application/json object { id*: string (SDK method_id:); code*: string; password: string (password); reauth_code: string } — password or reauth_code only when replacing a confirmed method 200 application/json Envelope plus object { data: object { recovery_codes: Array (shown once) } }
POST /v1/users/self/mfa/recovery-codes AuthResource#regenerate_recovery_codes Bearer token or X-Api-Key None required; application/json object { password: string (password); code: string } — one of the two is required (checked locally) 200 application/json Envelope plus object { data: object { recovery_codes: Array } }
DELETE /v1/users/self/mfa/{customId} AuthResource#delete_mfa_method Bearer token or X-Api-Key path customId*: string required; application/json object { password: string (password); code: string } — one of the two is required (checked locally) 200 application/json Envelope plus object { data: object { is_mfa_enabled: boolean } }
GET /v1/users/self/notification-preferences UserResource#notification_preferences Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: NotificationPreferences }
PUT /v1/users/self/notification-preferences UserResource#update_notification_preferences Bearer token or X-Api-Key None required; application/json NotificationPreferences 200 application/json Envelope plus object { data: NotificationPreferences }
GET /v1/users/self/stats UserResource#stats Bearer token or X-Api-Key query granularity: string
query month: string
None 200 application/json Envelope plus object { data: Array<DocumentStatsRow> }
POST /v1/verify SignerResource#verify_email signer-access-code query parameter None required; application/json object { verification-code*: string } 200 application/json Envelope
GET /v1/webhooks/event-types WebhookResource#list_event_types Bearer token or X-Api-Key None None 200 application/json Envelope plus object { data: Array<WebhookEventType> }

Error responses

OAuth endpoints are the exception to everything in this section: /v1/oauth/token and /v1/oauth/revoke report failures as the flat RFC 6749 §5.2 object {error, error_description}, and /v1/oauth/userinfo can report a framework error envelope. Both raise Assinafy::OAuthError, a subclass of Assinafy::ApiError that exposes #error and #error_description separately rather than flattening them into one message.

Assinafy can return errors as an application envelope:

{
  "status": 404,
  "data": null,
  "message": "Resource not found."
}

Framework errors use this shape:

{
  "name": "Not Found",
  "message": "Resource not found.",
  "code": 0,
  "status": 404
}

Typical statuses are 400 for invalid parameters or bodies, 401 for missing or invalid authentication, 404 for an unavailable resource, 409 for a state conflict, and 500 for a server failure. All non-success responses raise Assinafy::ApiError:

  • status_code contains the HTTP or envelope status.
  • message uses the API's message, error, or name value.
  • response_data preserves the parsed response body.
  • error_name and error_code expose framework name and code values when present.
  • context contains status_code and response_data for structured logging or support diagnostics, plus www_authenticate when the response carries that header.

Transport, timeout, and TLS failures raise Assinafy::NetworkError; caller-side validation failures raise Assinafy::ValidationError before a request is sent.

Operational notes

Template operations

The sandbox and SDK support these five template operations. Their request and response behavior is documented here so applications can use the complete template lifecycle. Confirm availability in the target Assinafy environment before making these operations part of a critical workflow.

Method Path Ruby SDK method Authentication Request / response
GET /v1/accounts/{account_id}/templates/{template_id} TemplateResource#get Bearer token or X-Api-Key No request body; returns an unwrapped Template-shaped object.
POST /v1/accounts/{account_id}/templates TemplateResource#create Bearer token or X-Api-Key Multipart PDF upload; returns an unwrapped Template-shaped object.
PUT /v1/accounts/{account_id}/templates/{template_id} TemplateResource#update Bearer token or X-Api-Key JSON partial update; returns an unwrapped Template-shaped object.
DELETE /v1/accounts/{account_id}/templates/{template_id} TemplateResource#delete Bearer token or X-Api-Key No request body; returns nil on success.
GET /v1/accounts/{account_id}/templates/{template_id}/pages/{page_id}/download TemplateResource#download_page Bearer token or X-Api-Key No request body; returns binary image bytes.

Assignment listing

GET /v1/assignments is scoped by the camelCase accountId query parameter. AssignmentResource#list supplies it from the client default or the per-call override.

Assignment optional fields

message must be a string; expires_at must be an ISO 8601 timestamp with a timezone at least one hour in the future, and copy_receivers must be an array of non-empty signer IDs. AssignmentResource.build_payload rejects other shapes locally, so Client#upload_and_request_signatures fails before it uploads a document or creates signers.

Base URL

base_url must be an absolute http/https URL with a host. Other schemes, scheme-less hosts, and relative paths raise Assinafy::ValidationError at construction rather than sending credentials to them. Configuration#base_url= and #timeout= apply the same validation. The User-Agent header is set on every request.

Document upload and tags

DocumentResource#upload sends only the multipart file part; the API names the document after the uploaded file name. Rename it with DocumentResource#rename. Documents and templates are limited to 25 MB, checked locally together with the .pdf extension and %PDF- header.

DocumentResource#list accepts tags as a comma-separated String or an Array of tag IDs, which the SDK joins with commas; matching documents carry every listed tag. DocumentResource#replace_tags and #append_tags accept arrays of tag IDs. Use a tag ID with DocumentResource#detach_tag.

KPI statistics

UserResource#stats and AccountResource#stats validate granularity (monthly or daily) and month (YYYY-MM) locally before sending.

OAuth response shapes

/v1/oauth/token, /v1/oauth/revoke, and /v1/oauth/userinfo deliberately do not use the {status, data, message} envelope: no standard OAuth or OIDC client would look for access_token or error inside a data key. /.well-known/oauth-protected-resource returns bare RFC 8615 metadata for the same reason. OAuthResource returns all four bodies unchanged.

/v1/oauth/token and /v1/oauth/revoke are unauthenticated routes that identify the client through client_id in the body, so the SDK strips X-Api-Key/Authorization from them. OAuthResource#authorization_server_metadata reaches a different host (auth.assinafy.com.br) and is stripped for the same reason. A URL override must be an absolute HTTPS URL without userinfo or fragment; anything else raises Assinafy::ValidationError.

/.well-known/oauth-protected-resource is served from the host root, outside the /v1 prefix that base_url carries.

Token refresh

The SDK does not refresh access tokens automatically. Persist expires_in alongside the token and call OAuthResource#refresh before expiry. A refresh token is issued only when offline_access was both requested and consented.

Every refresh returns a new refresh token, valid for another 30 days, and retires the one sent, so a connection only expires after 30 days without a refresh. Reusing a retired refresh token ends the whole connection. Store the new refresh and access tokens before using either, rebuild the client with the new access token, and run one refresh at a time per connection. OAuthResource#refresh, and #token with the refresh_token grant, raise Assinafy::Error rather than return a success whose refresh_token is missing, blank, or the one sent; handle that like invalid_grant.

The SDK never retries token requests; do not add middleware that does. After an ambiguous failure — a timeout, a reset connection, a 5xx — the server may have rotated the token without the response arriving. Re-read the stored refresh token: if it is still the one you sent, never send it again; ask the user to connect again. Proceed only if another worker has since stored a different one. Only a failure that provably happened before the request was sent (DNS resolution, a refused connection, a failed TLS handshake) is safe to retry. On an API 401, refresh once; if that fails, or on invalid_grant, ask the user to connect again.

When a user disconnects, revoke the refresh token in storage at that moment with OAuthResource#revoke, then delete the stored tokens. Revoking a rotated token also answers 200, so revoking a stale copy can look successful while the connection stays active.

Verification and notification methods

Verification and notification methods are coupled per signer: the omitted side is inferred from the other, and when both are omitted both are Email. Exactly one notification method is allowed. Allowed pairs: Email with Email, Whatsapp with Whatsapp, and DigitalCertificate with either. Email costs 0 credits; Whatsapp costs 0.45 credits (its WhatsApp notification, paid plans only); DigitalCertificate costs 0.5 credits per signer on top of its notification, shown in cost estimates under the breakdown code SignatureDigitalCertificate.

Digital-certificate signing

DigitalCertificate has the signer sign with their own ICP-Brasil certificate (A1 or A3) through the Web PKI browser extension, producing a qualified PAdES signature. It requires the Digital Certificate account feature, a CPF or CNPJ in the signer's government_id (accepted by both SignerResource#create and #update), and that the signer is alone in its signing step. A CPF requires that person's certificate (an e-CPF, or an e-CNPJ naming them as legal representative); a CNPJ requires an e-CNPJ for that company, from any of its representatives.

Certificate signers complete the signature in Assinafy's hosted signing flow, reached through the assignment's signing_urls. The SDK does not wrap the two-step Web PKI handshake (/signers/certificate/start, /signers/certificate/complete), whose authentication and request/response schemas are not part of the OpenAPI contract. Once the flow completes, the pades artifact returns the qualified signature.

Webhook endpoints and deliveries

An account can have 1 webhook endpoint, or up to 3 on paid plans; each has a distinct URL, its own events, and its own signing setting, and every active endpoint subscribed to an event receives it. WebhookResource#create_endpoint and #update_endpoint accept only url, email, events, name, is_active, and signing_enabled. #register, #get, and #inactivate (/webhooks/subscriptions, /webhooks/inactivate) act on the account's oldest endpoint; #register accepts only url, email, events, and is_active.

Each delivery is a JSON POST carrying webhook-id (stable across attempts of one event to one endpoint; use it to deduplicate), webhook-timestamp (Unix seconds), and, when signing is enabled, webhook-signature. Any 2xx is success. An event gets up to 2 attempts, 3 seconds apart; after 10 consecutive failed events, delivery to that endpoint pauses and only a sample of events is probed until one succeeds. WebhookResource#retry_dispatch forces a redelivery, and #list_dispatches filters by endpoint_id. The body is a WebhookEvent.

Signatures follow the Standard Webhooks specification: webhook-signature holds space-separated v1,<base64 HMAC-SHA256> entries over {webhook-id}.{webhook-timestamp}.{raw body}, keyed with the base64-decoded part of the secret after whsec_. WebhookVerifier#verify_delivery(raw_body, headers, tolerance: 300, now: Time.now.to_i) checks them in constant time and rejects timestamps more than tolerance seconds from now. It accepts Rails request.headers, a Rack env (HTTP_WEBHOOK_ID), or a plain Hash, and returns false rather than raising. WebhookVerifier#verify(raw_body, hex_signature) remains for receivers whose own gateway signs bodies with a hex HMAC-SHA256.

SDK-only helpers and aliases

These public functions do not map one-to-one to an API operation. Their source comments provide parameter, return-value, and usage details.

Public function Purpose Source documentation
Assinafy::Client.new Construct a client with keyword configuration. client.rb
Assinafy::Client.create Construct a client from positional API-key and account arguments. client.rb
Assinafy::Client.from_config, .from_hash Construct a client from string- or symbol-keyed configuration. client.rb
Client#faraday_connection Return the configured Faraday connection for advanced integration. client.rb
Client#upload_and_request_signatures Upload, optionally wait, create signers, and create a virtual assignment. client.rb
Client#auth, #oauth, #accounts, #users, #documents, #signers, #signer_documents, #assignments, #webhooks, #templates, #fields, #tags, #webhook_verifier Return the client's resource and helper instances. client.rb
Assinafy::Configuration.new, .from_hash Build configuration directly or from string/symbol keys. configuration.rb
Configuration#auth_headers Return the selected API-key, bearer, or empty authentication header set. configuration.rb
Configuration readers/writers: api_key, token, account_id, base_url, webhook_secret, timeout, logger Read or update configuration values; base_url= and timeout= validate like the constructor. Construct a new client to apply changes. configuration.rb
DocumentResource#get Alias for #details. document_resource.rb
DocumentResource#wait_until_ready Poll document details until processing succeeds, fails, or times out. document_resource.rb
DocumentResource#fully_signed?, #signing_progress Derive completion state from document assignment data. document_resource.rb
SignerResource#validate_create! Validate and normalize a signer-create body without a network request. signer_resource.rb
SignerResource#find_by_email Page through a successful search and return a case-insensitive match or nil. signer_resource.rb
SignerDocumentResource#document Alias for #current. signer_document_resource.rb
AuthResource#api_key Alias for #get_api_key. auth_resource.rb
WebhookResource#update Alias for #register (acts on the oldest endpoint). webhook_resource.rb
AssignmentResource.build_payload Validate and normalize virtual or collect assignment bodies locally. assignment_resource.rb
WebhookVerifier.new, #verify_delivery Verify a Standard Webhooks delivery (webhook-id, webhook-timestamp, webhook-signature) with the endpoint's whsec_ secret, rejecting timestamps outside the tolerance (default 300 seconds).
WebhookVerifier#verify Verify a hex HMAC-SHA256 signature added by the receiver's own gateway.
WebhookVerifier::SECRET_PREFIX, ::DEFAULT_TOLERANCE The whsec_ secret prefix and the default 300-second timestamp tolerance. webhook_verifier.rb
WebhookVerifier#extract_event, #event_type, #event_payload, #event_object, #event_subject, #event_data Parse and access webhook envelope fields; event_data is retained as a compatibility helper. webhook_verifier.rb
Assinafy::Error.new, #context Construct/read the SDK base error and its structured context. errors.rb
Assinafy::ApiError.new, .from_response, #status_code, #response_data, #error_name, #error_code Construct/read an API response error. errors.rb
Assinafy::ValidationError.new, #errors; Assinafy::NetworkError Represent caller-side validation and transport failures. errors.rb
Assinafy::OAuthError.new, .from_response, #error, #error_description Represent an OAuth endpoint failure; subclasses ApiError, so existing rescue clauses keep working. errors.rb
Assinafy::OAuth.generate_code_verifier, .code_challenge, .generate_state, .normalize_scope, .validate_code_verifier!, .authorization_url Build the PKCE pair, CSRF state, and authorization URL for the browser half of the OAuth flow. No network request. oauth.rb
Assinafy::OAuth::AUTHORIZATION_SERVER, ::AUTHORIZATION_SERVER_METADATA_URL, ::AUTHORIZATION_ENDPOINT, ::CODE_CHALLENGE_METHOD, ::SCOPES Published authorization-server endpoints and scopes. oauth.rb
AssignmentResource::VERIFICATION_METHODS, ::NOTIFICATION_METHODS The signer verification (Email, Whatsapp, DigitalCertificate) and notification (Email, Whatsapp) enums, validated locally by build_payload. assignment_resource.rb
Assinafy::Utils.handle_assinafy_response, .clean_params, .query_params, .body_params, .require_email, .require_expiration Internal public helpers used by resources for envelope and parameter normalization; applications should prefer resource methods. utils.rb
Assinafy::NullLogger#debug, #info, #warn, #error, #fatal, #unknown Internal no-op logger methods used when no logger is configured. null_logger.rb
Assinafy::VERSION Published SDK version constant. version.rb
Assinafy::USER_AGENT Version-derived Assinafy-Ruby-SDK/v[VERSION] request identifier. version.rb

Request and response examples

The resource methods linked above include request and response examples in their YARD documentation. The schema catalog below describes the published response objects and their nested properties.

Schema catalog

Every published schema and its nested properties is listed below. Required fields are marked per schema; operation-specific requirements and grant-specific OAuth requirements still apply.

Account

A workspace account (organization).

Property Type Required Nullable Constraints / description
resource string No No —
id string No No —
name string No No —
primary_color string No Yes —
secondary_color string No Yes —
notification_sender_type string No No enum: ["User", "Account"]
roles Array No No —
is_delete_allowed boolean No No —
created_at string (date-time) No No —

AccountTheme

An account's branding theme.

Property Type Required Nullable Constraints / description
account_name string No No —
primary_color string No No Hex color without leading #.
secondary_color string No Yes —
logo string No No URL to the account logo.

ApiKey

Property Type Required Nullable Constraints / description
api_key string No Yes —

Assignment

A request for signers to sign a document.

Property Type Required Nullable Constraints / description
resource string No No —
id string No No —
sender_email string (email) No No —
method string No No enum: ["virtual", "collect"]
expires_at string (date-time) No Yes —
message string No Yes —
signers Array<AssignmentSigner> No No —
copy_receivers Array No No —
items Array<AssignmentItem> No No —
summary AssignmentSummary No No —
signing_urls Array<SigningUrl> No No —

AssignmentItem

Property Type Required Nullable Constraints / description
id string No No —
page any JSON value No Yes —
signer object No No Signer responsible for this item.
field object No Yes Field definition associated with the item.
display_settings any JSON value No No Rendering metadata for the item. Collect items use the DisplaySettings schema; virtual and legacy items may return an empty or non-object value.
value any JSON value No Yes Captured value when completed.
completed boolean No No —

AssignmentSigner

A signer within an assignment: the base Signer plus per-assignment verification/notification details.

Property Type Required Nullable Constraints / description
resource string No No Present in single-resource responses.
id string No No —
full_name string No No —
email string (email) No Yes —
whatsapp_phone_number string No Yes E.164 format; normalized on save.
has_accepted_terms boolean No No —
verification_method string No Yes —
notification_methods Array No Yes —
step integer No Yes Sequential signing step (defaults to 1).
notified boolean No Yes —
completed boolean No Yes Only present in account-owner contexts.
notification_history Array<NotificationHistoryEntry> No Yes Per-channel delivery history for this signer (email + WhatsApp), most-recent send order.

AssignmentSummary

Property Type Required Nullable Constraints / description
signer_count integer No No —
completed_count integer No No —
signers Array No No —

AuthAccount

Property Type Required Nullable Constraints / description
id string No No —
name string No No —
roles Array No No —
is_delete_allowed boolean No No —
created_at string (date-time) No No —

AuthSession

A JWT access token plus the authenticated user and the accounts they belong to.

Property Type Required Nullable Constraints / description
access_token string No No —
user AuthUser No No —
accounts Array<AuthAccount> No No —

AuthUser

Property Type Required Nullable Constraints / description
id string No No —
name string No No —
email string (email) No No —
telephone string No Yes —
government_id string No Yes —
is_email_verified boolean No No —
has_accepted_terms boolean No No —
created_at string (date-time) No No —
to_be_deleted_at string (date-time) No Yes —

CostEstimate

Cost breakdown for an assignment plus current account balances.

Property Type Required Nullable Constraints / description
documents integer No No Documents consumed (always 1).
credits number No No Total notification credits needed.
needs_extra_document boolean No No True when the plan's document allowance is exhausted and an extra document will be charged from credits.
extra_document_cost number No No Credits charged for the extra document when needs_extra_document is true.
total_credits number No No —
breakdown Array<CostEstimateBreakdownItem> No No —
document_balance number No No —
credit_balance number No No —
has_sufficient_resources boolean No No —
blocking_reason string No Yes enum: ["PendingPayment", "InsufficientDocuments", "InsufficientCredits"]
message string No Yes —

CostEstimateBreakdownItem

Property Type Required Nullable Constraints / description
code string No No —
name string No No —
cost number No No —
quantity integer No No —
unit_cost number No No —

DisplaySettings

A field placement rectangle on a document page. Geometry values are pixels in Assinafy's 150-DPI page image, measured from the upper-left corner. Clients must keep the rectangle within the selected page's width and height; the API does not clamp out-of-bounds values.

Property Type Required Nullable Constraints / description
left number (float) Yes No minimum: 0; Horizontal distance from the page's left edge, in page-image pixels.
top number (float) Yes No minimum: 0; Vertical distance from the page's top edge, in page-image pixels.
width number (float) Yes No minimum: 0; Width of the placement rectangle, in page-image pixels.
height number (float) Yes No minimum: 0; Height of the placement rectangle, in page-image pixels.
fontFamily string No No Font-family presentation metadata.
fontSize number (float) Yes No minimum: 0; Font size in the 150-DPI page-image coordinate system.
backgroundColor string No No CSS-compatible background-color presentation metadata.

Document

A document and its current lifecycle state.

Property Type Required Nullable Constraints / description
resource string No No Present in single-resource responses.
id string No No —
account_id string No No —
template_id string No Yes —
name string No No —
status string No No Status code — see GET /v1/documents/statuses.
artifacts object No No Artifact download URLs keyed by name. Always original, plus thumbnail once one exists. A certificated document also carries certificated, certificate-page and bundle, and pades when it was signed with a digital certificate — the PAdES version holds the signers' ICP-Brasil signatures, which certification flattens out of the certificated PDF.
is_closed boolean No No —
signing_url string No No —
decline_reason string No Yes —
declined_by any JSON value No Yes —
tags Array No No —
tags[].id string No No —
tags[].name string No No —
assignment object No Yes Expanded assignment data when included via ?expand=assignment; null otherwise.
assignment.resource string No No —
assignment.id string No No —
assignment.sender_email string (email) No No —
assignment.method string No No enum: ["virtual", "collect"]
assignment.expires_at string (date-time) No Yes —
assignment.message string No Yes —
assignment.signers Array<AssignmentSigner> No No —
assignment.copy_receivers Array No No —
assignment.items Array<AssignmentItem> No No —
assignment.summary AssignmentSummary No No —
assignment.signing_urls Array<SigningUrl> No No —
pages Array<DocumentPage> No No —
created_at string (date-time) No No —
updated_at string (date-time) No No —

DocumentActivity

A document activity event.

Property Type Required Nullable Constraints / description
id integer No No —
event string No No Event type code.
message string No No —
payload object No Yes Event-specific payload snapshot. Keys vary per event.
origin object No Yes Request origin when available.
origin.ip string No No —
origin.user-agent string No No —
created_at string (date-time) No No —

DocumentPage

Property Type Required Nullable Constraints / description
id string No No —
number integer No No —
height integer No No —
width integer No No —
download_url string No No —

DocumentStatsRow

One period of the document-funnel KPI series. period is YYYY-MM (monthly) or YYYY-MM-DD (daily); series are zero-filled, no gaps. Signature requests come with two independent breakdowns: the signature_requests_notification_* counters split them by the channels the signer was notified on — a signer reached on more than one channel counts once per channel, so these add up to at least signature_requests — while the signature_requests_verification_* counters split them by how the signer's identity is verified, and since each request has exactly one verification method those four always add up to signature_requests.

Property Type Required Nullable Constraints / description
period string No No YYYY-MM (monthly) or YYYY-MM-DD (daily).
documents_uploaded integer No No —
documents_sent integer No No —
signature_requests integer No No —
signature_requests_notification_email integer No No Requests notified by e-mail.
signature_requests_notification_whatsapp integer No No Requests notified by WhatsApp.
signature_requests_notification_bypass integer No No Requests with no notification sent (Bypass).
signature_requests_verification_email integer No No Requests verified by an e-mail token.
signature_requests_verification_whatsapp integer No No Requests verified by a WhatsApp token.
signature_requests_verification_bypass integer No No Requests signed without token verification (Bypass).
signature_requests_verification_digital_certificate integer No No Requests signed with the signer's own ICP-Brasil digital certificate.
signature_requests_viewed integer No No Signature requests whose document was first viewed during the period.
signature_requests_completed integer No No Signature requests completed by individual signers during the period.
documents_certified integer No No —

DocumentStatus

Property Type Required Nullable Constraints / description
code string No No —
deletable boolean No No —

DocumentVerification

The verification result for a document looked up by signature hash. When not verified, most fields are null and is_valid is false.

Property Type Required Nullable Constraints / description
hash string No No —
id string No Yes —
agreement_code string No Yes Agreement code printed on the document certificate.
status string No Yes —
page_count string No Yes —
signer_count string No Yes —
completed_count integer No Yes —
completed_at string (date-time) No Yes —
verified_at string (date-time) No No —
is_valid boolean No No —
message string No No Reason when not valid.

Envelope

Standard success wrapper. Operations add their own data.

Property Type Required Nullable Constraints / description
status integer No No HTTP status code, mirrored in the body.
message string No No Human-readable message; empty on success.

ErrorEnvelope

Standard error wrapper. status mirrors the HTTP status code.

Property Type Required Nullable Constraints / description
status integer No No —
message string No No Human-readable error message.
data object No Yes —

Field

A reusable field definition.

Property Type Required Nullable Constraints / description
resource string No No —
id string No No —
name string No No —
type string No No —
regex string No Yes —
is_pre_defined boolean No No —
is_active boolean No No —
is_required boolean No No —
is_standard boolean No No —
is_read_only boolean No No —
is_visible boolean No No —

FieldType

A supported field/validation type.

Property Type Required Nullable Constraints / description
type string No No —
name string No No —

FieldValidation

The result of validating a value against a field definition.

Property Type Required Nullable Constraints / description
type string No No The field's validation type.
success boolean No No —
error_message string No No Empty when valid.

FieldValidationResult

A per-field result from a multi-field validation.

Property Type Required Nullable Constraints / description
field_id string No No —
type string No No —
success boolean No No —
error_message string No No —

NotificationHistoryEntry

A single notification delivery record for a signer channel.

Property Type Required Nullable Constraints / description
event string No No —
status string No No enum: ["sent", "failed"]
error_code string No Yes —
error_message string No Yes —
sent_at string (date-time) No Yes —
failed_at string (date-time) No Yes —

NotificationPreferences

Owner-facing document notifications, keyed by notification type. true means the e-mail is sent.

Property Type Required Nullable Constraints / description
DocumentCompleted boolean No No Every signer has signed and the document is certified.
SignerDeclined boolean No No A signer declined to sign.
DocumentCancelled boolean No No The document was cancelled.
DocumentAboutToExpire boolean No No The signature deadline is approaching.
DocumentExpired boolean No No The signature deadline passed.
DocumentExpirationReset boolean No No The signature deadline was extended.
DocumentProcessingFailed boolean No No An uploaded document could not be processed.
TemplateProcessingFailed boolean No No A template could not be processed.
SignerWhatsappFailed boolean No No A WhatsApp notification to a signer could not be delivered.

OAuthRevokeRequest

Body of POST /v1/oauth/revoke. Sent form-encoded per RFC 7009, or as JSON.

Property Type Required Nullable Constraints / description
token string Yes No —
token_type_hint string No No enum: ["access_token", "refresh_token"]
client_id string Yes No —
client_secret string No No —

OAuthTokenRequest

Body of POST /v1/oauth/token. Sent form-encoded per RFC 6749, or as JSON.

Property Type Required Nullable Constraints / description
grant_type string Yes No enum: ["authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange"]; urn:ietf:params:oauth:grant-type:token-exchange is for internal service clients only (Assinafy's own MCP server) — an ordinary confidential or public client authenticates with it and always gets invalid_client, exactly as an unrecognized client would. Everyday integrators use authorization_code and refresh_token.
code string No No —
redirect_uri string (uri) No No —
code_verifier string No No RFC 7636: 43-128 characters from [A-Za-z0-9-._~]. Shorter values are rejected with invalid_grant.
refresh_token string No No —
client_id string Yes No —
client_secret string No No Confidential clients only. Public clients authenticate with PKCE and are never issued a secret; the token-exchange grant requires a confidential, internal-service client and therefore always requires this.
resource string (uri) No No RFC 8707 resource indicator. For authorization_code/refresh_token, optional; when present it must be the resource value published by /.well-known/oauth-protected-resource and must match the one sent to /authorize, otherwise invalid_target. For the token-exchange grant it is REQUIRED and must equal this API's own resource identifier exactly (never a front-end resource such as the MCP server), otherwise invalid_target.
subject_token string No No Token-exchange grant only. The front-end resource's access token being traded in. Must be a live, original (never itself exchanged) token minted for a resource this server issues tokens for, other than this API's own audience.
subject_token_type string No No enum: ["urn:ietf:params:oauth:token-type:access_token"]; Token-exchange grant only. Required; only urn:ietf:params:oauth:token-type:access_token is supported.
requested_token_type string No No enum: ["urn:ietf:params:oauth:token-type:access_token"]; Token-exchange grant only. Optional; when present it must agree with the only type this server issues.

Signer

A signing party belonging to a workspace account.

Property Type Required Nullable Constraints / description
resource string No No Present in single-resource responses.
id string No No —
full_name string No No —
email string (email) No Yes —
whatsapp_phone_number string No Yes E.164 format; normalized on save.
has_accepted_terms boolean No No —

SignerSelf

The current signer, as returned by GET /v1/signers/self. Extends Signer with the signature-state flags that are only computed for the authenticated signer.

Property Type Required Nullable Constraints / description
resource string No No Present in single-resource responses.
id string No No —
full_name string No No —
email string (email) No Yes —
whatsapp_phone_number string No Yes E.164 format; normalized on save.
has_accepted_terms boolean No No —
has_signature boolean No No Whether the signer has a saved signature image stored.
has_initial boolean No No Whether the signer has a saved initials image stored.
is_signature_reusable boolean No No Whether the signer opted to reuse their saved signature/initials in future processes. When false, clients should not pre-render the saved image even if has_signature/has_initial is true.

SigningUrl

Property Type Required Nullable Constraints / description
signer_id string No No —
url string No No —

Tag

A workspace-scoped label. Names are unique per workspace (case-insensitive).

Property Type Required Nullable Constraints / description
resource string No No —
id string No No —
name string No No —
color string No Yes 6-char hex without leading #.
created_at string (date-time) No No —
updated_at string (date-time) No No —

Template

A reusable document template.

Property Type Required Nullable Constraints / description
resource string No No —
id string No No —
name string No No —
document_name string No Yes Default name for documents created from this template.
message string No Yes Default invitation message.
status string No No One of uploading, uploaded, processing, ready, failed.
pages Array<TemplatePage> No No —
roles Array<TemplateRole> No No —
tags Array No No —
tags[].id string No No —
tags[].name string No No —
default_document_tags Array No No Applied to documents created from this template; only returned by the single-template endpoint.
default_document_tags[].id string No No —
default_document_tags[].name string No No —
created_at string (date-time) No No —
updated_at string (date-time) No No —

TemplateFieldPlacement

Property Type Required Nullable Constraints / description
id string No No —
field_id string No No —
role_id string No No —
label string No No —
display_settings any JSON value No No Rendering metadata for the placement.
created_at string (date-time) No No —
updated_at string (date-time) No No —

TemplatePage

Property Type Required Nullable Constraints / description
id string No No —
number integer No No —
height integer No No —
width integer No No —
download_url string No No —
fields Array<TemplateFieldPlacement> No No —

TemplateRole

Property Type Required Nullable Constraints / description
id string No No —
name string No No —
assignment_type string No No —
created_at string (date-time) No No —
updated_at string (date-time) No No —

WebhookDispatch

A single webhook delivery-history entry.

Property Type Required Nullable Constraints / description
resource string No No Always activity_dispatching_history in single-resource responses.
id string No No Dispatch entry ID.
event string No No Event type that triggered the dispatch.
activity_id integer No No Internal activity ID associated with the dispatch.
endpoint_id string No Yes ID of the webhook endpoint the delivery was sent to (null once that endpoint is deleted).
endpoint string No Yes URL that received the request.
payload object No Yes JSON payload sent to the endpoint.
delivered boolean No No Whether delivery succeeded.
http_status integer No Yes HTTP status returned (null if connection failed).
response_body string No Yes Endpoint response body, truncated to 2000 chars.
error string No Yes Delivery error message, if any.
created_at string (date-time) No No —
updated_at string (date-time) No No —

WebhookEndpoint

A URL that receives the account's webhook events. Every active endpoint subscribed to an event receives it.

Property Type Required Nullable Constraints / description
id string No No Endpoint ID.
name string No Yes Label to tell endpoints apart.
url string (uri) No No URL that receives the events (http or https).
email string (email) No No Contact email for delivery-failure notices.
events Array No No Event types delivered to this endpoint.
is_active boolean No No Whether events are delivered to this endpoint.
signing_enabled boolean No No Whether deliveries carry a webhook-signature header.
created_at string (date-time) No No —
updated_at string (date-time) No No —

WebhookEndpointSecret

An endpoint's signing secret.

Property Type Required Nullable Constraints / description
secret string No No Standard Webhooks secret: whsec_ followed by the base64-encoded key.

WebhookEvent

Body of every webhook delivery. Timestamps in the body (created_at, and the *_at fields of subject/object) are Unix timestamps in seconds. subject and object are serialized from their current state when the delivery is sent.

Property Type Required Nullable Constraints / description
id integer Yes No ID of the activity that produced the event. Deduplicate on the webhook-id header instead.
event string Yes No Event type. See GET /v1/webhooks/event-types.
message string No Yes Reserved; currently always null.
payload object No Yes Event-specific parameters; keys vary per event.
origin object No Yes Where the action came from, when triggered by a request.
origin.ip string No No —
origin.user-agent string No No —
created_at integer Yes No When the event was recorded (Unix timestamp, seconds).
subject object Yes No Who performed the action: a User, Signer, or Account, plus a type property naming it.
object object Yes No What the action was performed on: a Document, Signer, or Template with its relations expanded, plus a type property naming it.
account_id string Yes No ID of the account that owns the event.

WebhookEventType

A subscribable webhook event type.

Property Type Required Nullable Constraints / description
id string No No Event type code.
description string No No When the event is triggered.

WebhookSubscription

An account's webhook subscription configuration: the account's oldest webhook endpoint.

Property Type Required Nullable Constraints / description
events Array No No Event types subscribed for delivery.
is_active boolean No No Whether webhook delivery is active.
url string No Yes Webhook endpoint URL.
email string No Yes Contact email for delivery notices.
updated_at string (date-time) No Yes —

WhatsappNotification

A rendered WhatsApp notification sent for an assignment, split into header/body/buttons as the signer would see them.

Property Type Required Nullable Constraints / description
sent_at integer No No Unix timestamp when sent.
header string No No —
body string No No —
buttons Array No No —
buttons[].text string No No The button label shown to the signer.
phone_number string No No Recipient phone (E.164).
signer_id string No No —