assinafy 2.1.0 → 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.
@@ -1,6 +1,6 @@
1
1
  # Assinafy Ruby SDK API Reference
2
2
 
3
- > Contract source: Assinafy API v1 OpenAPI 3.1.0, retrieved 2026-10-28 from
3
+ > Contract source: Assinafy API v1 OpenAPI 3.1.0, retrieved 2026-11-02 from
4
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
 
@@ -64,10 +64,10 @@ Required parameters and object properties are marked with `*`.
64
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)> } |
65
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 } } |
66
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)> } |
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; `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) } |
68
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)> } |
69
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) } |
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; `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) } |
71
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> } |
72
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) } |
73
73
  | GET | `/v1/accounts/{accountId}/logo` | `AccountResource#download_logo` | Bearer token or `X-Api-Key` | path `accountId*`: string | None | `200` `image/*` string (binary) |
@@ -78,10 +78,10 @@ Required parameters and object properties are marked with `*`.
78
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) } |
79
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) } |
80
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> } |
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 | 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)> } |
82
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)> } |
83
- | 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) } |
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`: 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) } |
85
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 } } |
86
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)> } |
87
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) } |
@@ -159,7 +159,7 @@ Required parameters and object properties are marked with `*`.
159
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 } } |
160
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
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 | None | `200` `application/json` [`Envelope`](#envelope) plus object { `data`: Array<[`DocumentStatsRow`](#documentstatsrow)> } |
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)> } |
163
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) |
164
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)> } |
165
165
 
@@ -273,7 +273,7 @@ require `documents:write`.
273
273
  ### KPI statistics
274
274
 
275
275
  `UserResource#stats` and `AccountResource#stats` validate `granularity` (`monthly` or `daily`) and `month`
276
- (`YYYY-MM`) locally before sending.
276
+ (`YYYY-MM`) locally before sending. Daily statistics require `month`.
277
277
 
278
278
  ### OAuth response shapes
279
279
 
@@ -1200,7 +1200,7 @@ A rendered WhatsApp notification sent for an assignment, split into header/body/
1200
1200
 
1201
1201
  | Property | Type | Required | Nullable | Constraints / description |
1202
1202
  | --- | --- | --- | --- | --- |
1203
- | `sent_at` | integer | No | No | Unix timestamp when sent. |
1203
+ | `sent_at` | string (date-time) | No | No | When the message was sent. |
1204
1204
  | `header` | string | No | No | — |
1205
1205
  | `body` | string | No | No | — |
1206
1206
  | `buttons` | Array<object> | No | No | — |
@@ -192,7 +192,7 @@ module Assinafy
192
192
  # @note Documented in the API reference, but gated on the account's plan:
193
193
  # this route answers 404 where the KPI feature is not enabled.
194
194
  # @param granularity [String, nil] `"monthly"` or `"daily"`
195
- # @param month [String, nil] e.g. `"2026-06"`
195
+ # @param month [String, nil] e.g. `"2026-06"`; required with daily granularity
196
196
  # @param account_id_override [String, nil]
197
197
  # @return [Array<Hash>] one KPI entry per period
198
198
  # @raise [Assinafy::ApiError] on an unsuccessful API response
@@ -712,7 +712,7 @@ module Assinafy
712
712
  # resource.whatsapp_notifications("document-id", "assignment-id")
713
713
  # # (no request body)
714
714
  # # => [
715
- # # { "sent_at" => 1710000000,
715
+ # # { "sent_at" => "2026-07-07T12:00:00Z",
716
716
  # # "header" => "Documento para assinatura: Contrato de Servico",
717
717
  # # "body" => "Oi, Maria.\n\nJoao Silva enviou um documento...",
718
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
@@ -50,6 +50,7 @@ module Assinafy
50
50
  body = with_explicit_regex(raw, body_params(raw))
51
51
  require_string(body['name'], 'Field name')
52
52
  require_string(body['type'], 'Field type')
53
+ require_string(body['regex'], 'Field regex') if body.key?('regex') && !body['regex'].nil?
53
54
  require_boolean(body['is_required'], 'is_required') if body.key?('is_required')
54
55
 
55
56
  call('Failed to create field definition') do
@@ -171,6 +172,7 @@ module Assinafy
171
172
  raw = require_payload(payload)
172
173
  body = with_explicit_regex(raw, body_params(raw))
173
174
  require_string(body['name'], 'Field name') if body.key?('name')
175
+ require_string(body['regex'], 'Field regex') if body.key?('regex') && !body['regex'].nil?
174
176
  require_boolean(body['is_active'], 'is_active') if body.key?('is_active')
175
177
 
176
178
  call('Failed to update field definition') do
@@ -420,6 +420,9 @@ module Assinafy
420
420
  doc_id = require_id(document_id, 'Document ID')
421
421
  body = body_params(require_payload(payload))
422
422
  code = require_signer_access_code(signer_access_code)
423
+ require_string(body['full_name'], 'Full name') if body.key?('full_name')
424
+ Utils.require_email(body['email']) if body.key?('email')
425
+ require_string(body['government_id'], 'Government ID') if body.key?('government_id')
423
426
 
424
427
  call('Failed to confirm signer data') do
425
428
  http_put("documents/#{doc_id}/signers/confirm-data", body,
@@ -52,7 +52,7 @@ module Assinafy
52
52
  #
53
53
  # @param payload [Hash]
54
54
  # @option payload [String] :name required tag display name
55
- # @option payload [String, nil] :color optional 6-character hex color
55
+ # @option payload [String, nil] :color optional 6-digit hex color, with or without `#`
56
56
  # @param account_id_override [String, nil]
57
57
  # @return [Hash] the created tag object
58
58
  # @raise [Assinafy::ValidationError] if `:name` is missing or blank
@@ -168,6 +168,10 @@ module Assinafy
168
168
  body['color'] = nil if explicit_nil_color?(raw)
169
169
 
170
170
  validate_tag_name!(body, require_name: require_name)
171
+ if body.key?('color') && !body['color'].nil?
172
+ color = require_string(body['color'], 'Tag color')
173
+ raise ValidationError.new('Tag color must be a 6-digit hex color') unless color.match?(/\A#?[0-9a-f]{6}\z/i)
174
+ end
171
175
 
172
176
  if !require_name && body.empty?
173
177
  raise ValidationError.new('Provide at least one of name or color to update')
@@ -86,7 +86,7 @@ module Assinafy
86
86
  # @note Documented in the API reference, but gated on the account's plan:
87
87
  # this route answers 404 where the KPI feature is not enabled.
88
88
  # @param granularity [String, nil] `"monthly"` or `"daily"`
89
- # @param month [String, nil] e.g. `"2026-06"`
89
+ # @param month [String, nil] e.g. `"2026-06"`; required with daily granularity
90
90
  # @return [Array<Hash>] one KPI entry per period
91
91
  # @raise [Assinafy::ApiError] on an unsuccessful API response
92
92
  # @raise [Assinafy::NetworkError] on transport or TLS failure
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Assinafy
4
- VERSION = '2.1.0'
4
+ VERSION = '2.1.1'
5
5
  USER_AGENT = "Assinafy-Ruby-SDK/v#{VERSION}".freeze
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: assinafy
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Assinafy SDK Contributors