assinafy 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.en.md +27 -4
- data/README.md +100 -1047
- data/docs/API_REFERENCE.md +154 -18
- data/lib/assinafy/client.rb +4 -0
- data/lib/assinafy/resources/account_resource.rb +2 -1
- data/lib/assinafy/resources/assignment_resource.rb +10 -11
- data/lib/assinafy/resources/base_resource.rb +3 -0
- data/lib/assinafy/resources/contract_resource.rb +450 -0
- data/lib/assinafy/resources/document_resource.rb +3 -0
- data/lib/assinafy/resources/field_resource.rb +2 -0
- data/lib/assinafy/resources/signer_resource.rb +3 -0
- data/lib/assinafy/resources/tag_resource.rb +5 -1
- data/lib/assinafy/resources/user_resource.rb +19 -7
- data/lib/assinafy/resources/webhook_resource.rb +35 -5
- data/lib/assinafy/version.rb +1 -1
- data/lib/assinafy.rb +1 -0
- data/sig/assinafy.rbs +18 -0
- metadata +4 -3
data/docs/API_REFERENCE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Assinafy Ruby SDK API Reference
|
|
2
2
|
|
|
3
|
-
> Contract source: Assinafy API v1 OpenAPI 3.1.0, retrieved 2026-
|
|
4
|
-
> `https://api.assinafy.com.br/v1/docs/openapi.json` (
|
|
3
|
+
> Contract source: Assinafy API v1 OpenAPI 3.1.0, retrieved 2026-11-02 from
|
|
4
|
+
> `https://api.assinafy.com.br/v1/docs/openapi.json` (90 paths, 118 operations, 49 schemas).
|
|
5
5
|
> `scripts/check_api_contract.rb` validates contract compatibility weekly.
|
|
6
6
|
|
|
7
7
|
This is the SDK-facing contract reference. Paths below are wire paths; Ruby methods return the unwrapped
|
|
@@ -50,6 +50,12 @@ Required parameters and object properties are marked with `*`.
|
|
|
50
50
|
| GET | `/v1/accounts/{accountId}` | `AccountResource#get` | Bearer token or `X-Api-Key` | path `accountId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Account`](#account) } |
|
|
51
51
|
| 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`](#envelope) plus object { `data`: [`Account`](#account) } |
|
|
52
52
|
| 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`](#envelope) plus object { `data`: Array<any> } |
|
|
53
|
+
| GET | `/v1/accounts/{accountId}/contracts` | `ContractResource#list` | Bearer token or `X-Api-Key`; OAuth `documents:read` | path `accountId*`: string<br>query `status`: comma-separated array of `draft`, `active`, `expired`, `terminated`<br>query `counterparty`, `search`, `end_date_from`, `end_date_to`, `ending_within_days`, `external_system`, `external_id`, `sort`, `expand`, `page`, `per-page` | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`DocumentContract`](#documentcontract)> }; pagination headers become `{ data:, meta: }` |
|
|
54
|
+
| GET | `/v1/accounts/{accountId}/documents/{documentId}/contract` | `ContractResource#get` | Bearer token or `X-Api-Key`; OAuth `documents:read` | path `accountId*`: string<br>path `documentId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`DocumentContract`](#documentcontract) or [`DocumentContractAmendment`](#documentcontractamendment) }; SDK returns `nil` on `404` |
|
|
55
|
+
| PUT | `/v1/accounts/{accountId}/documents/{documentId}/contract` | `ContractResource#update` | Bearer token or `X-Api-Key`; OAuth `documents:write` | path `accountId*`: string<br>path `documentId*`: string | required non-empty [`DocumentContractInput`](#documentcontractinput); explicit `nil` is sent as JSON null | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`DocumentContract`](#documentcontract) or [`DocumentContractAmendment`](#documentcontractamendment) }; `403` without contract tracking, `409` on stale `updated_at` |
|
|
56
|
+
| GET | `/v1/accounts/{accountId}/documents/{documentId}/contract/related` | `ContractResource#related` | Bearer token or `X-Api-Key`; OAuth `documents:read` | path `accountId*`: string<br>path `documentId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: root [`DocumentContract`](#documentcontract) with `amendments` }; SDK returns `nil` on `404` |
|
|
57
|
+
| POST | `/v1/accounts/{accountId}/documents/{documentId}/contract/renew` | `ContractResource#renew` | Bearer token or `X-Api-Key`; OAuth `documents:write` | path `accountId*`: string<br>path `documentId*`: string | optional; `application/json` object { `end_date`: string (date, nullable); `value`: number (nullable); `term`: integer; `updated_at`: string (date-time) }; a valid request requires `term` or `end_date` | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`DocumentContract`](#documentcontract) }; `403` without contract tracking, `409` on stale `updated_at` |
|
|
58
|
+
| POST | `/v1/accounts/{accountId}/documents/{documentId}/contract/terminate` | `ContractResource#terminate` | Bearer token or `X-Api-Key`; OAuth `documents:write` | path `accountId*`: string<br>path `documentId*`: string | optional; `application/json` object { `reason`: string (nullable, max 500); `updated_at`: string (date-time) } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`DocumentContract`](#documentcontract) }; `403` without contract tracking, `409` on stale `updated_at` |
|
|
53
59
|
| GET | `/v1/accounts/{accountId}/documents` | `DocumentResource#list` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>query `status`: string<br>query `method`: string<br>query `search`: string<br>query `tags`: string<br>query `sort`: string<br>query `page`: integer<br>query `per-page`: integer | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`Document`](#document)> } |
|
|
54
60
|
| 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`](#envelope) plus object { `data`: [`Document`](#document) } |
|
|
55
61
|
| GET | `/v1/accounts/{accountId}/documents/search` | `DocumentResource#search` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>query `search`: string<br>query `status`: string<br>query `page`: integer<br>query `per-page`: integer | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`Document`](#document)> } |
|
|
@@ -58,10 +64,10 @@ Required parameters and object properties are marked with `*`.
|
|
|
58
64
|
| POST | `/v1/accounts/{accountId}/documents/{documentId}/tags` | `DocumentResource#append_tags` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `documentId*`: string | required; `application/json` object { `tags`: Array<string> } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`Tag`](#tag)> } |
|
|
59
65
|
| DELETE | `/v1/accounts/{accountId}/documents/{documentId}/tags/{tagId}` | `DocumentResource#detach_tag` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `documentId*`: string<br>path `tagId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: object { `detached`: boolean } } |
|
|
60
66
|
| GET | `/v1/accounts/{accountId}/fields` | `FieldResource#list` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>query `include_inactive`: boolean<br>query `include_standard`: boolean | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`Field`](#field)> } |
|
|
61
|
-
| 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`](#envelope) plus object { `data`: [`Field`](#field) } |
|
|
67
|
+
| 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 or null; `is_required`: boolean } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Field`](#field) } |
|
|
62
68
|
| 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`](#envelope) plus object { `data`: Array<[`FieldValidationResult`](#fieldvalidationresult)> } |
|
|
63
69
|
| GET | `/v1/accounts/{accountId}/fields/{fieldId}` | `FieldResource#get` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `fieldId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Field`](#field) } |
|
|
64
|
-
| PUT | `/v1/accounts/{accountId}/fields/{fieldId}` | `FieldResource#update` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `fieldId*`: string | required; `application/json` object { `name`: string; `regex`: string; `is_active`: boolean } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Field`](#field) } |
|
|
70
|
+
| PUT | `/v1/accounts/{accountId}/fields/{fieldId}` | `FieldResource#update` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `fieldId*`: string | required; `application/json` object { `name`: string; `regex`: string or null; `is_active`: boolean } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Field`](#field) } |
|
|
65
71
|
| DELETE | `/v1/accounts/{accountId}/fields/{fieldId}` | `FieldResource#delete` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `fieldId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<any> } |
|
|
66
72
|
| POST | `/v1/accounts/{accountId}/fields/{fieldId}/validate` | `FieldResource#validate` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `fieldId*`: string | required; `application/json` object { `value*`: any JSON value } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`FieldValidation`](#fieldvalidation) } |
|
|
67
73
|
| GET | `/v1/accounts/{accountId}/logo` | `AccountResource#download_logo` | Bearer token or `X-Api-Key` | path `accountId*`: string | None | `200` `image/*` string (binary) |
|
|
@@ -72,10 +78,10 @@ Required parameters and object properties are marked with `*`.
|
|
|
72
78
|
| GET | `/v1/accounts/{accountId}/signers/{signerId}` | `SignerResource#get` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `signerId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Signer`](#signer) } |
|
|
73
79
|
| PUT | `/v1/accounts/{accountId}/signers/{signerId}` | `SignerResource#update` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `signerId*`: string | required; `application/json` object { `full_name`: string; `email`: string (email); `whatsapp_phone_number`: string; `government_id`: string } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Signer`](#signer) } |
|
|
74
80
|
| DELETE | `/v1/accounts/{accountId}/signers/{signerId}` | `SignerResource#delete` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `signerId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<any> } |
|
|
75
|
-
| GET | `/v1/accounts/{accountId}/stats` | `AccountResource#stats` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>query `granularity`: string<br>query `month`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`DocumentStatsRow`](#documentstatsrow)> } |
|
|
81
|
+
| GET | `/v1/accounts/{accountId}/stats` | `AccountResource#stats` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>query `granularity`: string<br>query `month`: string (`YYYY-MM`; required for daily) | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`DocumentStatsRow`](#documentstatsrow)> } |
|
|
76
82
|
| GET | `/v1/accounts/{accountId}/tags` | `TagResource#list` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>query `search`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`Tag`](#tag)> } |
|
|
77
|
-
| 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`](#envelope) plus object { `data`: [`Tag`](#tag) } |
|
|
78
|
-
| PUT | `/v1/accounts/{accountId}/tags/{tagId}` | `TagResource#update` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `tagId*`: string | required; `application/json` object { `name`: string; `color`: string } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Tag`](#tag) } |
|
|
83
|
+
| POST | `/v1/accounts/{accountId}/tags` | `TagResource#create` | Bearer token or `X-Api-Key` | path `accountId*`: string | required; `application/json` object { `name*`: string; `color`: 6-digit hex string (optional leading `#`) or null } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Tag`](#tag) } |
|
|
84
|
+
| PUT | `/v1/accounts/{accountId}/tags/{tagId}` | `TagResource#update` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `tagId*`: string | required; `application/json` object { `name`: string; `color`: 6-digit hex string (optional leading `#`) or null } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Tag`](#tag) } |
|
|
79
85
|
| DELETE | `/v1/accounts/{accountId}/tags/{tagId}` | `TagResource#delete` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `tagId*`: string<br>query `force`: boolean | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: object { `deleted`: boolean } } |
|
|
80
86
|
| GET | `/v1/accounts/{accountId}/templates` | `TemplateResource#list` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>query `search`: string<br>query `page`: integer<br>query `per-page`: integer | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`Template`](#template)> } |
|
|
81
87
|
| POST | `/v1/accounts/{accountId}/templates/{templateId}/documents` | `DocumentResource#create_from_template` | Bearer token or `X-Api-Key` | path `accountId*`: string<br>path `templateId*`: string | required; `application/json` object { `signers*`: Array<object { `role_id*`: string; `id*`: string; `verification_method`: string; `notification_methods`: Array<string>; `step`: integer }>; `editor_fields`: Array<object { `field_id*`: string; `value*`: string }>; `name`: string; `message`: string; `expires_at`: string (date-time); `tags`: Array<string> } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Document`](#document) } |
|
|
@@ -111,7 +117,7 @@ Required parameters and object properties are marked with `*`.
|
|
|
111
117
|
| POST | `/v1/documents/{documentId}/assignments/{assignmentId}` | `AssignmentResource#sign` | `signer-access-code` query parameter | path `documentId*`: string<br>path `assignmentId*`: string | required; `application/json` Array<object { `itemId*`: string; `fieldId*`: string; `pageId*`: string; `value*`: string }> | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: object } |
|
|
112
118
|
| PUT | `/v1/documents/{documentId}/assignments/{assignmentId}/reject` | `AssignmentResource#decline` | `signer-access-code` query parameter | path `documentId*`: string<br>path `assignmentId*`: string | required; `application/json` object { `decline_reason*`: string } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<any> } |
|
|
113
119
|
| PUT | `/v1/documents/{documentId}/assignments/{assignmentId}/reset-expiration` | `AssignmentResource#reset_expiration` | Bearer token or `X-Api-Key` | path `documentId*`: string<br>path `assignmentId*`: string | required; `application/json` object { `expires_at*`: string (date-time) or `null` to clear } | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`Assignment`](#assignment) } |
|
|
114
|
-
| POST | `/v1/documents/{documentId}/assignments/{assignmentId}/signers/{signerId}/estimate-resend-cost` | `AssignmentResource#estimate_resend_cost` | Bearer token or `X-Api-Key` | path `documentId*`: string<br>path `assignmentId*`: string<br>path `signerId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`
|
|
120
|
+
| POST | `/v1/documents/{documentId}/assignments/{assignmentId}/signers/{signerId}/estimate-resend-cost` | `AssignmentResource#estimate_resend_cost` | Bearer token or `X-Api-Key` | path `documentId*`: string<br>path `assignmentId*`: string<br>path `signerId*`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`ResendCostEstimate`](#resendcostestimate) } |
|
|
115
121
|
| GET | `/v1/documents/{documentId}/assignments/{assignmentId}/signers/{signerId}/identity-verification` | `AssignmentResource#identity_review` | Bearer token or `X-Api-Key` | path `documentId*`, `assignmentId*`, `signerId*`: string | None | `200` envelope data [`SignerIdentityReview`](#signeridentityreview); `404` when no verification exists |
|
|
116
122
|
| GET | `/v1/documents/{documentId}/assignments/{assignmentId}/signers/{signerId}/identity-verification/images/{name}` | `AssignmentResource#identity_review_image` | Bearer token or `X-Api-Key` | path `documentId*`, `assignmentId*`, `signerId*`: string; `name*`: enum `document_front`, `document_back`, `document_pdf`, `face` | None | `200` binary `image/jpeg`, `image/png` or `application/pdf`, `Cache-Control: no-store`; `404` unless evidence exists and review is InReview |
|
|
117
123
|
| POST | `/v1/documents/{documentId}/assignments/{assignmentId}/signers/{signerId}/identity-verification/review` | `AssignmentResource#decide_identity_review` | Bearer token or `X-Api-Key` | path `documentId*`, `assignmentId*`, `signerId*`: string | required; `application/json` { `decision*`: enum `Approved`, `Rejected`; `note`: string or null (max 2000 characters) } | `200` envelope data [`SignerIdentityReview`](#signeridentityreview); `400` unless InReview and document is pending_signature or pending_identity_review |
|
|
@@ -151,9 +157,9 @@ Required parameters and object properties are marked with `*`.
|
|
|
151
157
|
| 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`](#envelope) plus object { `data`: object { `recovery_codes`: Array<string> (shown once) } } |
|
|
152
158
|
| 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`](#envelope) plus object { `data`: object { `recovery_codes`: Array<string> } } |
|
|
153
159
|
| 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`](#envelope) plus object { `data`: object { `is_mfa_enabled`: boolean } } |
|
|
154
|
-
| GET | `/v1/users/self/notification-preferences` | `UserResource#notification_preferences` |
|
|
155
|
-
| PUT | `/v1/users/self/notification-preferences` | `UserResource#update_notification_preferences` |
|
|
156
|
-
| GET | `/v1/users/self/stats` | `UserResource#stats` | Bearer token or `X-Api-Key` | query `granularity`: string<br>query `month`: string | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`DocumentStatsRow`](#documentstatsrow)> } |
|
|
160
|
+
| GET | `/v1/users/self/notification-preferences` | `UserResource#notification_preferences` | User bearer token or `X-Api-Key`; unavailable to third-party OAuth apps | None | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`NotificationPreferences`](#notificationpreferences) } |
|
|
161
|
+
| PUT | `/v1/users/self/notification-preferences` | `UserResource#update_notification_preferences` | User bearer token or `X-Api-Key`; unavailable to third-party OAuth apps | None | required; `application/json` [`NotificationPreferences`](#notificationpreferences) | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: [`NotificationPreferences`](#notificationpreferences) } |
|
|
162
|
+
| GET | `/v1/users/self/stats` | `UserResource#stats` | Bearer token or `X-Api-Key` | query `granularity`: string<br>query `month`: string (`YYYY-MM`; required for daily) | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`DocumentStatsRow`](#documentstatsrow)> } |
|
|
157
163
|
| POST | `/v1/verify` | `SignerResource#verify_email` | `signer-access-code` query parameter | None | required; `application/json` object { `verification-code*`: string } | `200` `application/json` [`Envelope`](#envelope) |
|
|
158
164
|
| GET | `/v1/webhooks/event-types` | `WebhookResource#list_event_types` | Bearer token or `X-Api-Key` | None | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`WebhookEventType`](#webhookeventtype)> } |
|
|
159
165
|
|
|
@@ -249,10 +255,25 @@ locally together with the `.pdf` extension and `%PDF-` header.
|
|
|
249
255
|
with commas; matching documents carry every listed tag. `DocumentResource#replace_tags` and `#append_tags` accept
|
|
250
256
|
arrays of tag IDs. Use a tag ID with `DocumentResource#detach_tag`.
|
|
251
257
|
|
|
258
|
+
### Contract tracking
|
|
259
|
+
|
|
260
|
+
Contract terms belong to an existing document; setting terms never uploads, sends, or signs the document.
|
|
261
|
+
`ContractResource#update` creates or partially changes the terms. Explicit `nil` values remain JSON null so they
|
|
262
|
+
clear nullable fields. To record a signed amendment, renewal, or termination instrument, upload that document and
|
|
263
|
+
set its `parent_document_id`, `relation_type`, and changed terms; the delta applies after the instrument is
|
|
264
|
+
certificated. `#get` reads the terms or an instrument, and `#related` always reads the root family.
|
|
265
|
+
|
|
266
|
+
The hourly lifecycle moves active contracts through notice, expiry, and automatic renewal. `#renew` starts the
|
|
267
|
+
next term immediately; sending the current `term` makes a lost-response retry safe. `#terminate` closes the
|
|
268
|
+
contract and records its optional reason. Writers can send the `updated_at` they read as an optimistic-lock
|
|
269
|
+
precondition; the API refuses a stale write with `409`. Reads remain available without the contract-tracking
|
|
270
|
+
plan, while writes answer `403` when the plan lacks the feature. OAuth reads require `documents:read`, and writes
|
|
271
|
+
require `documents:write`.
|
|
272
|
+
|
|
252
273
|
### KPI statistics
|
|
253
274
|
|
|
254
275
|
`UserResource#stats` and `AccountResource#stats` validate `granularity` (`monthly` or `daily`) and `month`
|
|
255
|
-
(`YYYY-MM`) locally before sending.
|
|
276
|
+
(`YYYY-MM`) locally before sending. Daily statistics require `month`.
|
|
256
277
|
|
|
257
278
|
### OAuth response shapes
|
|
258
279
|
|
|
@@ -357,7 +378,9 @@ if lost, delete and recreate the endpoint. `#list_endpoints(url: registered_url)
|
|
|
357
378
|
`#delete_endpoint_by_url(registered_url)` deletes that endpoint, returning `nil`. `WebhookResource#create_endpoint`
|
|
358
379
|
and `#update_endpoint` accept only `url`, `email`, `events`, `name`, `is_active`, and `signing_enabled`.
|
|
359
380
|
`#register`, `#get`, and `#inactivate` (`/webhooks/subscriptions`, `/webhooks/inactivate`) act on the account's
|
|
360
|
-
oldest endpoint; `#register` accepts only `url`, `email`, `events`, and `is_active`.
|
|
381
|
+
oldest endpoint; `#register` accepts only `url`, `email`, `events`, and `is_active`. New or changed endpoint URLs
|
|
382
|
+
must be absolute HTTPS URLs; the SDK rejects other schemes locally, while the API also refuses private, loopback,
|
|
383
|
+
link-local, and other reserved destination addresses.
|
|
361
384
|
|
|
362
385
|
Each delivery is a JSON `POST` carrying `webhook-id` (stable across attempts of one event to one endpoint; use it to
|
|
363
386
|
deduplicate), `webhook-timestamp` (Unix seconds), and, when signing is enabled, `webhook-signature`. Any `2xx` is
|
|
@@ -385,7 +408,7 @@ return-value, and usage details.
|
|
|
385
408
|
| `Assinafy::Client.from_config`, `.from_hash` | Construct a client from string- or symbol-keyed configuration. | [`client.rb`](../lib/assinafy/client.rb) |
|
|
386
409
|
| `Client#faraday_connection` | Return the configured Faraday connection for advanced integration. | [`client.rb`](../lib/assinafy/client.rb) |
|
|
387
410
|
| `Client#upload_and_request_signatures` | Upload, optionally wait, create signers, and create a virtual assignment. | [`client.rb`](../lib/assinafy/client.rb) |
|
|
388
|
-
| `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`](../lib/assinafy/client.rb) |
|
|
411
|
+
| `Client#auth`, `#oauth`, `#accounts`, `#users`, `#documents`, `#contracts`, `#signers`, `#signer_documents`, `#assignments`, `#webhooks`, `#templates`, `#fields`, `#tags`, `#webhook_verifier` | Return the client's resource and helper instances. | [`client.rb`](../lib/assinafy/client.rb) |
|
|
389
412
|
| `Assinafy::Configuration.new`, `.from_hash` | Build configuration directly or from string/symbol keys. | [`configuration.rb`](../lib/assinafy/configuration.rb) |
|
|
390
413
|
| `Configuration#auth_headers` | Return the selected API-key, bearer, or empty authentication header set. | [`configuration.rb`](../lib/assinafy/configuration.rb) |
|
|
391
414
|
| 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`](../lib/assinafy/configuration.rb) |
|
|
@@ -439,6 +462,8 @@ A workspace account (organization).
|
|
|
439
462
|
| `notification_sender_type` | string | No | No | enum: `["User", "Account"]` |
|
|
440
463
|
| `roles` | Array<string> | No | No | — |
|
|
441
464
|
| `is_delete_allowed` | boolean | No | No | — |
|
|
465
|
+
| `limits` | object | No | No | Current-plan limits; present only on the single-account response. More keys may be added. |
|
|
466
|
+
| `limits.webhook_endpoints` | integer | No | No | Maximum webhook endpoints: 1, or 3 with the Multiple Webhooks feature. |
|
|
442
467
|
| `created_at` | string (date-time) | No | No | — |
|
|
443
468
|
|
|
444
469
|
### AccountTheme
|
|
@@ -466,7 +491,9 @@ A request for signers to sign a document.
|
|
|
466
491
|
| --- | --- | --- | --- | --- |
|
|
467
492
|
| `resource` | string | No | No | — |
|
|
468
493
|
| `id` | string | No | No | — |
|
|
469
|
-
| `
|
|
494
|
+
| `document_id` | string | No | Yes | Document this assignment belongs to; null only after the document is deleted. |
|
|
495
|
+
| `created_at` | string (date-time) | No | No | — |
|
|
496
|
+
| `sender_email` | string (email) | No | Yes | Null once the sender has deleted their account. |
|
|
470
497
|
| `method` | string | No | No | enum: `["virtual", "collect"]` |
|
|
471
498
|
| `expires_at` | string (date-time) | No | Yes | — |
|
|
472
499
|
| `message` | string | No | Yes | — |
|
|
@@ -608,12 +635,14 @@ A document and its current lifecycle state.
|
|
|
608
635
|
| `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. |
|
|
609
636
|
| `is_closed` | boolean | No | No | — |
|
|
610
637
|
| `signing_url` | string | No | No | — |
|
|
638
|
+
| `verification_code` | string | No | Yes | Code printed on the certificate page; null until certificated. |
|
|
639
|
+
| `verification_url` | string (uri) | No | Yes | Public verification page; null until certificated. |
|
|
611
640
|
| `decline_reason` | string | No | Yes | — |
|
|
612
641
|
| `declined_by` | any JSON value | No | Yes | — |
|
|
613
642
|
| `tags` | Array<object> | No | No | — |
|
|
614
643
|
| `tags[].id` | string | No | No | — |
|
|
615
644
|
| `tags[].name` | string | No | No | — |
|
|
616
|
-
| `assignment` | object | No | Yes |
|
|
645
|
+
| `assignment` | object | No | Yes | Included by list/details/signer-list/template-generation responses; search and upload omit it. Only rename follows `?expand=assignment`. |
|
|
617
646
|
| `assignment.resource` | string | No | No | — |
|
|
618
647
|
| `assignment.id` | string | No | No | — |
|
|
619
648
|
| `assignment.sender_email` | string (email) | No | No | — |
|
|
@@ -626,6 +655,7 @@ A document and its current lifecycle state.
|
|
|
626
655
|
| `assignment.summary` | [`AssignmentSummary`](#assignmentsummary) | No | No | — |
|
|
627
656
|
| `assignment.signing_urls` | Array<[`SigningUrl`](#signingurl)> | No | No | — |
|
|
628
657
|
| `pages` | Array<[`DocumentPage`](#documentpage)> | No | No | — |
|
|
658
|
+
| `has_contract` | boolean | No | No | Only on workspace `GET /documents/{documentId}` when contract tracking is available. A missing key means unknown. |
|
|
629
659
|
| `created_at` | string (date-time) | No | No | — |
|
|
630
660
|
| `updated_at` | string (date-time) | No | No | — |
|
|
631
661
|
|
|
@@ -644,6 +674,85 @@ A document activity event.
|
|
|
644
674
|
| `origin.user-agent` | string | No | No | — |
|
|
645
675
|
| `created_at` | string (date-time) | No | No | — |
|
|
646
676
|
|
|
677
|
+
### DocumentContract
|
|
678
|
+
|
|
679
|
+
Contract terms tracked on a document. The single-contract and related-family reads can include amendments; the
|
|
680
|
+
workspace list can include the document when `expand=document` is requested.
|
|
681
|
+
|
|
682
|
+
| Property | Type | Required | Nullable | Constraints / description |
|
|
683
|
+
| --- | --- | --- | --- | --- |
|
|
684
|
+
| `resource` | string | No | No | `document_contract` in single-resource responses. |
|
|
685
|
+
| `document_id` | string | No | No | Document that owns the terms. |
|
|
686
|
+
| `status` | string | No | No | enum: `["draft", "active", "expired", "terminated"]` |
|
|
687
|
+
| `counterparty_name` | string | No | Yes | — |
|
|
688
|
+
| `counterparty_taxpayer_id` | string | No | Yes | Normalized CPF/CNPJ, digits only. |
|
|
689
|
+
| `value` | number | No | Yes | At most two decimal places. |
|
|
690
|
+
| `currency` | string | No | Yes | ISO 4217 code; defaults to BRL when a value is set. |
|
|
691
|
+
| `start_date` | string (date) | No | Yes | — |
|
|
692
|
+
| `end_date` | string (date) | No | Yes | — |
|
|
693
|
+
| `auto_renew` | boolean | No | No | — |
|
|
694
|
+
| `renewal_term_months` | integer | No | Yes | — |
|
|
695
|
+
| `notice_period_days` | integer | No | Yes | — |
|
|
696
|
+
| `term` | integer | No | No | Renewal term number, starting at 1. |
|
|
697
|
+
| `owner_id` | string | No | Yes | Active workspace member responsible for lifecycle email. |
|
|
698
|
+
| `metadata` | object | No | Yes | Up to 50 caller-defined string values. |
|
|
699
|
+
| `external_references` | Array<object> | No | No | IDs in outside systems, sorted by system and ID. |
|
|
700
|
+
| `external_references[].system` | string | No | No | Outside system name. |
|
|
701
|
+
| `external_references[].id` | string | No | No | ID in that system. |
|
|
702
|
+
| `document` | [`Document`](#document) | No | No | Only on list results with `expand=document`. |
|
|
703
|
+
| `amendments` | Array<[`DocumentContractAmendment`](#documentcontractamendment)> | No | No | Only on single-contract/family reads. |
|
|
704
|
+
| `created_at` | string (date-time) | No | No | — |
|
|
705
|
+
| `updated_at` | string (date-time) | No | No | Moves on every direct or lifecycle change. |
|
|
706
|
+
|
|
707
|
+
### DocumentContractAmendment
|
|
708
|
+
|
|
709
|
+
A document linked as an amendment, renewal, or termination instrument. Its terms are a delta applied to the
|
|
710
|
+
parent after this document is certificated.
|
|
711
|
+
|
|
712
|
+
| Property | Type | Required | Nullable | Constraints / description |
|
|
713
|
+
| --- | --- | --- | --- | --- |
|
|
714
|
+
| `resource` | string | No | No | `document_contract_amendment` in single-resource responses. |
|
|
715
|
+
| `document_id` | string | No | No | The instrument document. |
|
|
716
|
+
| `document_name` | string | No | No | Instrument document name. |
|
|
717
|
+
| `parent_document_id` | string | No | No | Root contract document. |
|
|
718
|
+
| `relation_type` | string | No | No | enum: `["amendment", "renewal", "termination"]` |
|
|
719
|
+
| `number` | integer | No | Yes | Applied position; null while pending. |
|
|
720
|
+
| `status` | string | No | No | enum: `["pending", "applied"]` |
|
|
721
|
+
| `document_status` | string | No | No | Current lifecycle status of the instrument document. |
|
|
722
|
+
| `apply_error` | string | No | Yes | Why a signed instrument has not applied yet. |
|
|
723
|
+
| `currency` | string | No | Yes | Currency used by amount values in `terms` and `changes`. |
|
|
724
|
+
| `terms` | object | No | Yes | Only contract terms changed by this instrument. |
|
|
725
|
+
| `changes` | object | No | Yes | Changed fields as `{ from:, to: }`, previewed while pending and fixed once applied. |
|
|
726
|
+
| `applied_at` | string (date-time) | No | Yes | — |
|
|
727
|
+
| `created_at` | string (date-time) | No | No | — |
|
|
728
|
+
| `updated_at` | string (date-time) | No | No | — |
|
|
729
|
+
|
|
730
|
+
### DocumentContractInput
|
|
731
|
+
|
|
732
|
+
Partial body for setting terms or linking an instrument. Only sent fields change. JSON null clears a nullable
|
|
733
|
+
term; for a pending instrument it removes that term from the delta. `external_references` replaces the whole list.
|
|
734
|
+
|
|
735
|
+
| Property | Type | Required | Nullable | Constraints / description |
|
|
736
|
+
| --- | --- | --- | --- | --- |
|
|
737
|
+
| `status` | string | No | No | enum: `["draft", "active", "expired", "terminated"]`; closed statuses are creation-only. |
|
|
738
|
+
| `counterparty_name` | string | No | Yes | Maximum 255 characters. |
|
|
739
|
+
| `counterparty_taxpayer_id` | string | No | Yes | Valid formatted or unformatted CPF/CNPJ. |
|
|
740
|
+
| `value` | number | No | Yes | 0–9,999,999,999,999.99; at most two decimal places. |
|
|
741
|
+
| `currency` | string | No | Yes | Three-letter code, stored uppercase. |
|
|
742
|
+
| `start_date` | string (date) | No | Yes | `YYYY-MM-DD`, year 1000 or later. |
|
|
743
|
+
| `end_date` | string (date) | No | Yes | On or after `start_date`. |
|
|
744
|
+
| `auto_renew` | boolean | No | Yes | Null resets to false. |
|
|
745
|
+
| `renewal_term_months` | integer | No | Yes | 1–600; defaults to 12 when unset. |
|
|
746
|
+
| `notice_period_days` | integer | No | Yes | 0–3650. |
|
|
747
|
+
| `owner_id` | string | No | Yes | Active member of the workspace. |
|
|
748
|
+
| `metadata` | object | No | Yes | Up to 50 keys of 1–40 letters, digits, `_`, `-`, or `.`, each holding at most 500 characters. |
|
|
749
|
+
| `external_references` | Array<object> | No | Yes | At most 20; null or an empty array clears the list. |
|
|
750
|
+
| `external_references[].system` | string | Yes | No | Up to 64 letters, digits, `_`, `-`, or `.`; stored lowercase. |
|
|
751
|
+
| `external_references[].id` | string | Yes | No | Up to 255 characters. |
|
|
752
|
+
| `parent_document_id` | string | No | Yes | Links to a contract family; null unlinks a pending instrument. |
|
|
753
|
+
| `relation_type` | string | No | No | Required for the first link; enum: `["amendment", "renewal", "termination"]`. |
|
|
754
|
+
| `updated_at` | string (date-time) | No | Yes | Optional optimistic-lock value; a stale value returns `409`. Null is last-write-wins. |
|
|
755
|
+
|
|
647
756
|
### DocumentPage
|
|
648
757
|
|
|
649
758
|
| Property | Type | Required | Nullable | Constraints / description |
|
|
@@ -795,6 +904,10 @@ Owner-facing document notifications, keyed by notification type. `true` means th
|
|
|
795
904
|
| `DocumentProcessingFailed` | boolean | No | No | An uploaded document could not be processed. |
|
|
796
905
|
| `TemplateProcessingFailed` | boolean | No | No | A template could not be processed. |
|
|
797
906
|
| `SignerWhatsappFailed` | boolean | No | No | A WhatsApp notification to a signer could not be delivered. |
|
|
907
|
+
| `ContractRenewalNotice` | boolean | No | No | A tracked contract entered its notice period. |
|
|
908
|
+
| `ContractExpiring` | boolean | No | No | A tracked contract ends in 45 or 30 days. |
|
|
909
|
+
| `ContractExpired` | boolean | No | No | A tracked contract ended without renewal. |
|
|
910
|
+
| `ContractRenewed` | boolean | No | No | A tracked contract was automatically renewed into its next term. |
|
|
798
911
|
|
|
799
912
|
### OAuthRevokeRequest
|
|
800
913
|
|
|
@@ -825,6 +938,20 @@ Body of `POST /v1/oauth/token`. Sent form-encoded per RFC 6749, or as JSON.
|
|
|
825
938
|
| `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. |
|
|
826
939
|
| `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. |
|
|
827
940
|
|
|
941
|
+
### ResendCostEstimate
|
|
942
|
+
|
|
943
|
+
Credits needed to resend one signer's notification. A reminder consumes no document allowance.
|
|
944
|
+
|
|
945
|
+
| Property | Type | Required | Nullable | Constraints / description |
|
|
946
|
+
| --- | --- | --- | --- | --- |
|
|
947
|
+
| `total` | number | No | No | Sum of the breakdown costs. |
|
|
948
|
+
| `breakdown` | Array<object> | No | No | Per-charge resend costs. |
|
|
949
|
+
| `breakdown[].code` | string | No | No | For example `NotificationWhatsappResend`. |
|
|
950
|
+
| `breakdown[].name` | string | No | No | Human-readable charge name. |
|
|
951
|
+
| `breakdown[].cost` | number | No | No | Credits charged for this item. |
|
|
952
|
+
| `credit_balance` | number | No | Yes | Available credits; null when credits are unlimited. |
|
|
953
|
+
| `has_sufficient_credits` | boolean | No | No | Whether the workspace can pay for the resend. |
|
|
954
|
+
|
|
828
955
|
### Signer
|
|
829
956
|
|
|
830
957
|
A signing party belonging to a workspace account.
|
|
@@ -987,6 +1114,10 @@ A single webhook delivery-history entry.
|
|
|
987
1114
|
| `endpoint` | string | No | Yes | URL that received the request. |
|
|
988
1115
|
| `payload` | object | No | Yes | JSON payload sent to the endpoint. |
|
|
989
1116
|
| `delivered` | boolean | No | No | Whether delivery succeeded. |
|
|
1117
|
+
| `webhook_id` | string | No | Yes | Stable `webhook-id` header across attempts of this event to this endpoint. |
|
|
1118
|
+
| `attempt` | integer | No | Yes | Attempt number, starting at 1. |
|
|
1119
|
+
| `kind` | string | No | No | enum: `["scheduled", "probe", "manual"]` |
|
|
1120
|
+
| `will_retry` | boolean | No | No | Whether another attempt follows this entry. |
|
|
990
1121
|
| `http_status` | integer | No | Yes | HTTP status returned (null if connection failed). |
|
|
991
1122
|
| `response_body` | string | No | Yes | Endpoint response body, truncated to 2000 chars. |
|
|
992
1123
|
| `error` | string | No | Yes | Delivery error message, if any. |
|
|
@@ -999,12 +1130,15 @@ A URL that receives the account's webhook events. Every active endpoint subscrib
|
|
|
999
1130
|
|
|
1000
1131
|
| Property | Type | Required | Nullable | Constraints / description |
|
|
1001
1132
|
| --- | --- | --- | --- | --- |
|
|
1133
|
+
| `resource` | string | No | No | Always `activity_event_subscription` in single-resource responses. |
|
|
1002
1134
|
| `id` | string | No | No | Endpoint ID. |
|
|
1003
1135
|
| `name` | string | No | Yes | Label to tell endpoints apart. |
|
|
1004
|
-
| `url` | string (uri) | No | No | URL that receives the events
|
|
1136
|
+
| `url` | string (uri) | No | No | HTTPS URL that receives the events. |
|
|
1005
1137
|
| `email` | string (email) | No | No | Contact email for delivery-failure notices. |
|
|
1006
1138
|
| `events` | Array<string> | No | No | Event types delivered to this endpoint. |
|
|
1007
1139
|
| `is_active` | boolean | No | No | Whether events are delivered to this endpoint. |
|
|
1140
|
+
| `is_held` | boolean | No | No | Whether deliveries are paused after repeated failures. |
|
|
1141
|
+
| `held_since` | integer | No | Yes | Unix timestamp when the pause began; null while deliveries run. |
|
|
1008
1142
|
| `signing_enabled` | boolean | No | No | Whether deliveries carry a `webhook-signature` header. |
|
|
1009
1143
|
| `created_at` | string (date-time) | No | No | — |
|
|
1010
1144
|
| `updated_at` | string (date-time) | No | No | — |
|
|
@@ -1054,6 +1188,8 @@ An account's webhook subscription configuration: the account's oldest webhook en
|
|
|
1054
1188
|
| --- | --- | --- | --- | --- |
|
|
1055
1189
|
| `events` | Array<string> | No | No | Event types subscribed for delivery. |
|
|
1056
1190
|
| `is_active` | boolean | No | No | Whether webhook delivery is active. |
|
|
1191
|
+
| `is_held` | boolean | No | No | Whether deliveries are paused after repeated failures. |
|
|
1192
|
+
| `held_since` | integer | No | Yes | Unix timestamp when the pause began; null while deliveries run. |
|
|
1057
1193
|
| `url` | string | No | Yes | Webhook endpoint URL. |
|
|
1058
1194
|
| `email` | string | No | Yes | Contact email for delivery notices. |
|
|
1059
1195
|
| `updated_at` | string (date-time) | No | Yes | — |
|
|
@@ -1064,7 +1200,7 @@ A rendered WhatsApp notification sent for an assignment, split into header/body/
|
|
|
1064
1200
|
|
|
1065
1201
|
| Property | Type | Required | Nullable | Constraints / description |
|
|
1066
1202
|
| --- | --- | --- | --- | --- |
|
|
1067
|
-
| `sent_at` |
|
|
1203
|
+
| `sent_at` | string (date-time) | No | No | When the message was sent. |
|
|
1068
1204
|
| `header` | string | No | No | — |
|
|
1069
1205
|
| `body` | string | No | No | — |
|
|
1070
1206
|
| `buttons` | Array<object> | No | No | — |
|
data/lib/assinafy/client.rb
CHANGED
|
@@ -33,6 +33,8 @@ module Assinafy
|
|
|
33
33
|
attr_reader :users
|
|
34
34
|
# @return [Resources::DocumentResource]
|
|
35
35
|
attr_reader :documents
|
|
36
|
+
# @return [Resources::ContractResource]
|
|
37
|
+
attr_reader :contracts
|
|
36
38
|
# @return [Resources::SignerResource]
|
|
37
39
|
attr_reader :signers
|
|
38
40
|
# @return [Resources::SignerDocumentResource]
|
|
@@ -84,6 +86,7 @@ module Assinafy
|
|
|
84
86
|
@accounts = Resources::AccountResource.new(@connection, account_id, @logger)
|
|
85
87
|
@users = Resources::UserResource.new(@connection, nil, @logger)
|
|
86
88
|
@documents = Resources::DocumentResource.new(@connection, account_id, @logger)
|
|
89
|
+
@contracts = Resources::ContractResource.new(@connection, account_id, @logger)
|
|
87
90
|
@signers = Resources::SignerResource.new(@connection, account_id, @logger)
|
|
88
91
|
@signer_documents = Resources::SignerDocumentResource.new(@connection, nil, @logger)
|
|
89
92
|
@assignments = Resources::AssignmentResource.new(@connection, account_id, @logger)
|
|
@@ -190,6 +193,7 @@ module Assinafy
|
|
|
190
193
|
# # },
|
|
191
194
|
# # assignment: {
|
|
192
195
|
# # "resource" => "assignment", "id" => "assignment-id",
|
|
196
|
+
# # "document_id" => "document-id", "created_at" => "2026-06-05T21:21:19Z",
|
|
193
197
|
# # "sender_email" => "sender@example.com", "method" => "virtual",
|
|
194
198
|
# # "expires_at" => nil, "message" => "Please review and sign",
|
|
195
199
|
# # "signers" => [{ "id" => "signer-id", "full_name" => "Example Signer",
|
|
@@ -90,6 +90,7 @@ module Assinafy
|
|
|
90
90
|
# 'name' => 'MT',
|
|
91
91
|
# 'primary_color' => nil,
|
|
92
92
|
# 'secondary_color' => nil,
|
|
93
|
+
# 'limits' => { 'webhook_endpoints' => 1 },
|
|
93
94
|
# 'created_at' => '2026-05-12T18:05:11Z'
|
|
94
95
|
# }
|
|
95
96
|
def get(account_id_override = nil)
|
|
@@ -191,7 +192,7 @@ module Assinafy
|
|
|
191
192
|
# @note Documented in the API reference, but gated on the account's plan:
|
|
192
193
|
# this route answers 404 where the KPI feature is not enabled.
|
|
193
194
|
# @param granularity [String, nil] `"monthly"` or `"daily"`
|
|
194
|
-
# @param month [String, nil] e.g. `"2026-06"
|
|
195
|
+
# @param month [String, nil] e.g. `"2026-06"`; required with daily granularity
|
|
195
196
|
# @param account_id_override [String, nil]
|
|
196
197
|
# @return [Array<Hash>] one KPI entry per period
|
|
197
198
|
# @raise [Assinafy::ApiError] on an unsuccessful API response
|
|
@@ -303,6 +303,8 @@ module Assinafy
|
|
|
303
303
|
# data: [
|
|
304
304
|
# {
|
|
305
305
|
# 'id' => 'assignment-id',
|
|
306
|
+
# 'document_id' => 'document-id',
|
|
307
|
+
# 'created_at' => '2026-06-05T21:21:19Z',
|
|
306
308
|
# 'sender_email' => 'sender@example.com',
|
|
307
309
|
# 'method' => 'virtual',
|
|
308
310
|
# 'expires_at' => nil,
|
|
@@ -342,6 +344,7 @@ module Assinafy
|
|
|
342
344
|
# # "message" => "Please sign" }
|
|
343
345
|
# # => {
|
|
344
346
|
# # "resource" => "assignment", "id" => "assignment-id",
|
|
347
|
+
# # "document_id" => "document-id", "created_at" => "2026-06-05T21:21:19Z",
|
|
345
348
|
# # "sender_email" => "sender@example.com", "method" => "virtual",
|
|
346
349
|
# # "expires_at" => nil, "message" => "Please sign",
|
|
347
350
|
# # "signers" => [{ "id" => "signer-id", "full_name" => "Example Signer",
|
|
@@ -475,9 +478,7 @@ module Assinafy
|
|
|
475
478
|
# @param document_id [String]
|
|
476
479
|
# @param assignment_id [String]
|
|
477
480
|
# @param signer_id [String]
|
|
478
|
-
# @return [Hash] cost
|
|
479
|
-
# total_credits, breakdown[], document_balance, credit_balance, has_sufficient_resources,
|
|
480
|
-
# blocking_reason, message)
|
|
481
|
+
# @return [Hash] resend cost (`total`, `breakdown`, `credit_balance`, `has_sufficient_credits`)
|
|
481
482
|
# @raise [Assinafy::ApiError] on an unsuccessful API response
|
|
482
483
|
# @raise [Assinafy::NetworkError] on transport or TLS failure
|
|
483
484
|
# @raise [Assinafy::ValidationError] on invalid required input
|
|
@@ -486,13 +487,11 @@ module Assinafy
|
|
|
486
487
|
# resource.estimate_resend_cost("document-id", "assignment-id", "signer-id")
|
|
487
488
|
# # (no request body)
|
|
488
489
|
# # => {
|
|
489
|
-
# # "
|
|
490
|
-
# # "
|
|
491
|
-
# #
|
|
492
|
-
# #
|
|
493
|
-
# #
|
|
494
|
-
# # "document_balance" => 10, "credit_balance" => 100,
|
|
495
|
-
# # "has_sufficient_resources" => true, "blocking_reason" => nil, "message" => nil
|
|
490
|
+
# # "total" => 0.45,
|
|
491
|
+
# # "breakdown" => [{ "code" => "NotificationWhatsappResend",
|
|
492
|
+
# # "name" => "Whatsapp Notification Resend", "cost" => 0.45 }],
|
|
493
|
+
# # "credit_balance" => 100,
|
|
494
|
+
# # "has_sufficient_credits" => true
|
|
496
495
|
# # }
|
|
497
496
|
def estimate_resend_cost(document_id, assignment_id, signer_id)
|
|
498
497
|
doc_id = require_id(document_id, 'Document ID')
|
|
@@ -713,7 +712,7 @@ module Assinafy
|
|
|
713
712
|
# resource.whatsapp_notifications("document-id", "assignment-id")
|
|
714
713
|
# # (no request body)
|
|
715
714
|
# # => [
|
|
716
|
-
# # { "sent_at" =>
|
|
715
|
+
# # { "sent_at" => "2026-07-07T12:00:00Z",
|
|
717
716
|
# # "header" => "Documento para assinatura: Contrato de Servico",
|
|
718
717
|
# # "body" => "Oi, Maria.\n\nJoao Silva enviou um documento...",
|
|
719
718
|
# # "buttons" => [{ "text" => "Abrir documento" }],
|
|
@@ -95,6 +95,9 @@ module Assinafy
|
|
|
95
95
|
unless granularity.nil? || STATS_GRANULARITIES.include?(granularity)
|
|
96
96
|
raise ValidationError.new('granularity must be monthly or daily')
|
|
97
97
|
end
|
|
98
|
+
if granularity == 'daily' && month.nil?
|
|
99
|
+
raise ValidationError.new('month is required when granularity is daily')
|
|
100
|
+
end
|
|
98
101
|
unless month.nil? || (month.is_a?(String) && month.match?(/\A\d{4}-(0[1-9]|1[0-2])\z/))
|
|
99
102
|
raise ValidationError.new('month must be YYYY-MM')
|
|
100
103
|
end
|