@assinafy/sdk 2.2.0 → 2.4.0

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.
package/dist/index.d.ts CHANGED
@@ -22,9 +22,41 @@ type SignatureImageType = 'signature' | 'initial' | AnyString;
22
22
  type AnyString = string & {};
23
23
  /** Assignment methods supported by the API. */
24
24
  type AssignmentMethod = 'virtual' | 'collect';
25
- /** Verification methods accepted by assignment signer entries. */
25
+ /**
26
+ * How a signer proves who they are before signing.
27
+ *
28
+ * | Value | How the signer is verified | Requirements | Cost per signer |
29
+ * | --- | --- | --- | --- |
30
+ * | `Email` | One-time code sent by e-mail (the default). | An `email`. | 0 credits |
31
+ * | `Whatsapp` | One-time code sent over WhatsApp. | A `whatsapp_phone_number`; paid plan. | 0.45 credits |
32
+ * | `DigitalCertificate` | The signer signs with their own ICP-Brasil certificate — **A1** (software, a file on the machine) or **A3** (hardware, a token or smartcard) — through the Web PKI browser extension, producing a qualified PAdES signature. | Digital Certificate feature (Standard/Pro); `government_id` (CPF, or CNPJ naming the signer as legal representative); the signer must be alone in their signing step. | 2 credits + notification |
33
+ *
34
+ * A1 and A3 are certificate *media*, chosen by the signer in their browser at
35
+ * signing time. The API models both as the single `DigitalCertificate` value —
36
+ * there is no separate `A1`/`A3` field to send, and the resulting PAdES
37
+ * signature is qualified either way.
38
+ *
39
+ * Verification is coupled to {@link AssignmentNotificationMethod}: the
40
+ * verification code travels on the notification channel, so `Email` pairs only
41
+ * with `Email` and `Whatsapp` only with `Whatsapp`. `DigitalCertificate`
42
+ * carries no code and may be announced over either channel. The SDK rejects an
43
+ * invalid pairing before the request; the API answers `400`.
44
+ *
45
+ * Send neither field to get `Email`/`Email`; send one and the other is
46
+ * inferred from it.
47
+ */
26
48
  type AssignmentVerificationMethod = 'Email' | 'Whatsapp' | 'DigitalCertificate';
27
- /** Notification methods accepted by assignment signer entries. */
49
+ /**
50
+ * How the signing invitation reaches the signer. Exactly one per signer.
51
+ *
52
+ * | Value | Requirements | Cost per signer |
53
+ * | --- | --- | --- |
54
+ * | `Email` | An `email`. | 0 credits |
55
+ * | `Whatsapp` | A `whatsapp_phone_number`; paid plan. | 0.45 credits |
56
+ *
57
+ * Notifications are charged when the assignment is created and again on every
58
+ * resend. See {@link AssignmentVerificationMethod} for the pairing rules.
59
+ */
28
60
  type AssignmentNotificationMethod = 'Email' | 'Whatsapp';
29
61
  /** Minimal logger contract (compatible with console, pino, winston, etc.). */
30
62
  interface Logger {
@@ -271,9 +303,13 @@ interface IAssignmentCostSigner {
271
303
  */
272
304
  interface IEstimateAssignmentCostPayload {
273
305
  method?: AssignmentMethod;
274
- /** Required for `virtual`; `{}` prices the default Email channel. */
275
- signers?: IAssignmentCostSigner[];
276
- /** Required for `collect`; signer descriptors are optional in that mode. */
306
+ /**
307
+ * Required for both methods — the API rejects an estimate without it, and
308
+ * per-signer `verification_method` is what the estimate prices. `{}` prices
309
+ * the default Email channel.
310
+ */
311
+ signers: IAssignmentCostSigner[];
312
+ /** Required for `collect`. */
277
313
  entries?: IAssignmentEntry[];
278
314
  }
279
315
  /** A signer as embedded inside an assignment (richer than the bare {@link ISigner}). */
@@ -1110,6 +1146,129 @@ interface IUpdateTagPayload {
1110
1146
  /** Pass `null` to clear the color; omit to leave unchanged. */
1111
1147
  color?: string | null;
1112
1148
  }
1149
+ /**
1150
+ * Permission an OAuth application can request.
1151
+ *
1152
+ * Known literals stay suggested in editors while any server-added scope still
1153
+ * type-checks (see {@link AnyString}). The authoritative list is
1154
+ * `scopes_supported` in
1155
+ * {@link IOAuthAuthorizationServerMetadata}.
1156
+ */
1157
+ type OAuthScope = 'documents:read' | 'documents:write' | 'templates:read' | 'templates:write' | 'account:read' | 'openid' | 'profile' | 'email' | 'offline_access' | AnyString;
1158
+ /**
1159
+ * RFC 9728 protected-resource metadata served at
1160
+ * `https://api.assinafy.com.br/.well-known/oauth-protected-resource`.
1161
+ *
1162
+ * Served bare, without the `{ status, message, data }` envelope, as RFC 8615
1163
+ * requires. `scopes_supported` omits `offline_access`, which is a request-time
1164
+ * signal to the authorization server rather than a permission this API checks.
1165
+ */
1166
+ interface IOAuthProtectedResourceMetadata {
1167
+ /** Canonical identifier of this API, e.g. `https://api.assinafy.com.br`. */
1168
+ resource: string;
1169
+ /** Issuers allowed to mint tokens for it, e.g. `['https://auth.assinafy.com.br']`. */
1170
+ authorization_servers: string[];
1171
+ /** Scopes this API accepts. */
1172
+ scopes_supported: string[];
1173
+ /** How a token may be presented; Assinafy accepts `header` only. */
1174
+ bearer_methods_supported: string[];
1175
+ }
1176
+ /**
1177
+ * RFC 8414 authorization-server metadata served at
1178
+ * `{issuer}/.well-known/oauth-authorization-server`.
1179
+ *
1180
+ * The browser-facing `authorization_endpoint` lives on the authorization server
1181
+ * while `token_endpoint` and friends live on this API, so read the URLs from
1182
+ * here rather than deriving them from one host.
1183
+ */
1184
+ interface IOAuthAuthorizationServerMetadata {
1185
+ /** Issuer identifier; must equal the URL the document was fetched from. */
1186
+ issuer: string;
1187
+ /** Browser-facing consent URL. */
1188
+ authorization_endpoint: string;
1189
+ /** Token endpoint, on the API host. */
1190
+ token_endpoint: string;
1191
+ revocation_endpoint?: string;
1192
+ userinfo_endpoint?: string;
1193
+ jwks_uri?: string;
1194
+ scopes_supported?: string[];
1195
+ response_types_supported?: string[];
1196
+ grant_types_supported?: string[];
1197
+ /** Assinafy supports `S256` only; plain PKCE is rejected. */
1198
+ code_challenge_methods_supported?: string[];
1199
+ token_endpoint_auth_methods_supported?: string[];
1200
+ /** RFC 9207. `true` means the callback carries `iss` and clients must check it. */
1201
+ authorization_response_iss_parameter_supported?: boolean;
1202
+ client_id_metadata_document_supported?: boolean;
1203
+ }
1204
+ /**
1205
+ * Everything one authorization attempt needs, returned by
1206
+ * {@link OAuthResource.createAuthorizationUrl}.
1207
+ *
1208
+ * Store every field except `url` in the user's session: the callback handler
1209
+ * needs `state` and `issuer` to prove the response is yours, the token exchange
1210
+ * needs `codeVerifier`, and `nonce` validates the `id_token`.
1211
+ */
1212
+ interface IOAuthAuthorizationRequest {
1213
+ /** Absolute URL to send the browser to with a full page navigation. */
1214
+ url: string;
1215
+ /** Single-use CSRF value echoed back on the redirect URI. */
1216
+ state: string;
1217
+ /** RFC 7636 code verifier; never leaves your server after this. */
1218
+ codeVerifier: string;
1219
+ /** Issuer expected in the callback's `iss` parameter. */
1220
+ issuer: string;
1221
+ /** Present when `openid` was requested; compare it to the `id_token` claim. */
1222
+ nonce?: string;
1223
+ }
1224
+ /**
1225
+ * Validated authorization response read off the redirect URI by
1226
+ * {@link OAuthResource.readAuthorizationCallback}.
1227
+ */
1228
+ interface IOAuthAuthorizationCallback {
1229
+ /** Single-use authorization code. Expires 60 seconds after approval. */
1230
+ code: string;
1231
+ /** The `state` value, already checked against the stored one. */
1232
+ state: string;
1233
+ /** The `iss` value, already checked against the expected issuer. */
1234
+ issuer?: string;
1235
+ }
1236
+ /**
1237
+ * RFC 6749 §5.1 token response. Returned flat, without this API's
1238
+ * `{ status, message, data }` envelope.
1239
+ */
1240
+ interface IOAuthTokenResponse {
1241
+ access_token: string;
1242
+ /** Always `Bearer`. */
1243
+ token_type: string;
1244
+ /** Access-token lifetime in seconds; Assinafy issues 3600. */
1245
+ expires_in: number;
1246
+ /**
1247
+ * Present only when `offline_access` was requested and granted. Every
1248
+ * refresh returns a new one and retires the old one — persist it before
1249
+ * using the access token.
1250
+ */
1251
+ refresh_token?: string | null;
1252
+ /**
1253
+ * Scopes actually granted to the access token. Read this instead of
1254
+ * assuming the request was honoured in full; `offline_access` never appears
1255
+ * here because it is a request-time signal, not a permission.
1256
+ */
1257
+ scope?: string;
1258
+ /** Signed OIDC identity token (RS256). Present only when `openid` was granted. */
1259
+ id_token?: string | null;
1260
+ }
1261
+ /** OpenID Connect claims returned by `GET /oauth/userinfo`. */
1262
+ interface IOAuthUserInfo {
1263
+ /** Stable user identifier. Always present. */
1264
+ sub: string;
1265
+ /** Requires the `profile` scope. */
1266
+ name?: string | null;
1267
+ /** Requires the `email` scope. */
1268
+ email?: string | null;
1269
+ /** Requires the `email` scope. */
1270
+ email_verified?: boolean | null;
1271
+ }
1113
1272
 
1114
1273
  /** Maximum upload size accepted by the API (hard limit, 25 MB). */
1115
1274
  declare const MAX_UPLOAD_BYTES: number;
@@ -2778,7 +2937,8 @@ declare class AssignmentResource extends BaseResource {
2778
2937
  * }
2779
2938
  * ```
2780
2939
  * @throws {ValidationError} If `documentId` is missing, a `virtual` request
2781
- * has no signer entry, or a `collect` request has no field-placement entry.
2940
+ * has no signer entry, or a `collect` request has no signer entry or no
2941
+ * field-placement entry.
2782
2942
  * @throws {ApiError} If the API rejects the request.
2783
2943
  *
2784
2944
  * @example
@@ -3988,6 +4148,506 @@ declare class AuthenticationResource extends BaseResource {
3988
4148
  private absoluteUrl;
3989
4149
  }
3990
4150
 
4151
+ /** Token-endpoint client authentication methods Assinafy accepts. */
4152
+ type TokenEndpointAuthOptions = {
4153
+ /** The application's `client_id` from Settings → OAuth applications. */
4154
+ clientId: string;
4155
+ /**
4156
+ * The application's `client_secret`. Confidential applications only —
4157
+ * public ones authenticate with PKCE and are never issued a secret. Never
4158
+ * ship it in browser, mobile, or repository code.
4159
+ */
4160
+ clientSecret?: string;
4161
+ };
4162
+ /**
4163
+ * OAuth 2.1 + OpenID Connect endpoints for applications acting inside *other
4164
+ * people's* workspaces.
4165
+ *
4166
+ * Use this resource only when your product is connected by its users. To
4167
+ * automate your own workspace, keep using an API key and ignore everything
4168
+ * here.
4169
+ *
4170
+ * Two hosts are involved on purpose: the consent page lives on the
4171
+ * authorization server (`https://auth.assinafy.com.br`) while the token,
4172
+ * revocation and userinfo endpoints live on this API. Both are published by
4173
+ * {@link OAuthResource.getAuthorizationServerMetadata}, so nothing needs
4174
+ * hardcoding.
4175
+ *
4176
+ * The full round trip:
4177
+ *
4178
+ * 1. {@link OAuthResource.createAuthorizationUrl} — mint PKCE + `state`, build
4179
+ * the consent URL, store the returned request in the user's session.
4180
+ * 2. Redirect the browser there; the user picks **one** workspace and approves.
4181
+ * 3. {@link OAuthResource.readAuthorizationCallback} — check `state` and `iss`
4182
+ * on your redirect URI, and surface a declined consent as an
4183
+ * {@link OAuthError}.
4184
+ * 4. {@link OAuthResource.exchangeCode} — swap the 60-second code for tokens.
4185
+ * 5. Build a per-connection client with that token and read the one workspace
4186
+ * it covers:
4187
+ * ```ts
4188
+ * const connected = new AssinafyClient({ token: tokens.access_token });
4189
+ * const { data } = await connected.workspaces.list();
4190
+ * const accountId = data[0]?.id;
4191
+ * ```
4192
+ * 6. {@link OAuthResource.refreshToken} before the hour is up (requires
4193
+ * `offline_access`), and {@link OAuthResource.revokeToken} when the user
4194
+ * disconnects.
4195
+ *
4196
+ * Two facts that cause most integration bugs: a token works for exactly one
4197
+ * workspace (any other answers `403`), and a connection expires 30 days after
4198
+ * approval no matter how often it is refreshed.
4199
+ *
4200
+ * @example
4201
+ * ```ts
4202
+ * const client = new AssinafyClient(); // no credentials needed
4203
+ *
4204
+ * // Step 1 — before redirecting the user
4205
+ * const request = await client.oauth.createAuthorizationUrl({
4206
+ * clientId: process.env.ASSINAFY_CLIENT_ID!,
4207
+ * redirectUri: 'https://myapp.com/oauth/callback',
4208
+ * scopes: ['documents:read', 'documents:write', 'offline_access'],
4209
+ * });
4210
+ * session.oauth = request; // state + codeVerifier + issuer
4211
+ * response.redirect(request.url);
4212
+ *
4213
+ * // Step 3/4 — on https://myapp.com/oauth/callback
4214
+ * const { code } = client.oauth.readAuthorizationCallback(query, session.oauth);
4215
+ * const tokens = await client.oauth.exchangeCode({
4216
+ * code,
4217
+ * codeVerifier: session.oauth.codeVerifier,
4218
+ * redirectUri: 'https://myapp.com/oauth/callback',
4219
+ * clientId: process.env.ASSINAFY_CLIENT_ID!,
4220
+ * clientSecret: process.env.ASSINAFY_CLIENT_SECRET,
4221
+ * });
4222
+ * ```
4223
+ */
4224
+ declare class OAuthResource extends BaseResource {
4225
+ private readonly publicHttp;
4226
+ constructor(http: AxiosInstance, defaultAccountId?: string, logger?: Logger, publicHttp?: AxiosInstance);
4227
+ /**
4228
+ * Read this API's protected-resource metadata
4229
+ * (`GET /.well-known/oauth-protected-resource`).
4230
+ *
4231
+ * Served at the API host root — not under `/v1` — and bare, without the
4232
+ * `{ status, message, data }` envelope, as RFC 8615 requires. Use it to
4233
+ * discover which authorization server may issue tokens for this API and
4234
+ * which scopes it accepts.
4235
+ *
4236
+ * Request body: none. Authentication: none.
4237
+ *
4238
+ * @returns The metadata document:
4239
+ * ```jsonc
4240
+ * {
4241
+ * "resource": "https://api.assinafy.com.br",
4242
+ * "authorization_servers": ["https://auth.assinafy.com.br"],
4243
+ * "scopes_supported": [
4244
+ * "documents:read", "documents:write",
4245
+ * "templates:read", "templates:write",
4246
+ * "account:read", "openid", "profile", "email"
4247
+ * ],
4248
+ * "bearer_methods_supported": ["header"]
4249
+ * }
4250
+ * ```
4251
+ * `offline_access` is deliberately absent: it is a request-time signal to
4252
+ * the authorization server, not a permission this API enforces.
4253
+ * @throws {ApiError} If the host does not publish the document.
4254
+ *
4255
+ * @example
4256
+ * ```ts
4257
+ * const metadata = await client.oauth.getProtectedResourceMetadata();
4258
+ * console.log(metadata.authorization_servers[0]);
4259
+ * ```
4260
+ */
4261
+ getProtectedResourceMetadata(): Promise<IOAuthProtectedResourceMetadata>;
4262
+ /**
4263
+ * Read the authorization server's metadata
4264
+ * (`GET {issuer}/.well-known/oauth-authorization-server`, RFC 8414).
4265
+ *
4266
+ * Every endpoint URL an OAuth client needs comes from here, so nothing has
4267
+ * to be hardcoded. The document is served by the authorization server, a
4268
+ * different host from this API.
4269
+ *
4270
+ * @param issuer - Issuer to read. Defaults to the first entry of
4271
+ * {@link OAuthResource.getProtectedResourceMetadata}, which costs one extra
4272
+ * request — pass the issuer to skip it.
4273
+ * @returns The metadata document:
4274
+ * ```jsonc
4275
+ * {
4276
+ * "issuer": "https://auth.assinafy.com.br",
4277
+ * "authorization_endpoint": "https://auth.assinafy.com.br/oauth/authorize",
4278
+ * "token_endpoint": "https://api.assinafy.com.br/v1/oauth/token",
4279
+ * "revocation_endpoint": "https://api.assinafy.com.br/v1/oauth/revoke",
4280
+ * "userinfo_endpoint": "https://api.assinafy.com.br/v1/oauth/userinfo",
4281
+ * "jwks_uri": "https://auth.assinafy.com.br/.well-known/jwks.json",
4282
+ * "scopes_supported": ["documents:read", "documents:write", "templates:read",
4283
+ * "templates:write", "account:read", "openid",
4284
+ * "profile", "email", "offline_access"],
4285
+ * "response_types_supported": ["code"],
4286
+ * "grant_types_supported": ["authorization_code", "refresh_token"],
4287
+ * "code_challenge_methods_supported": ["S256"],
4288
+ * "token_endpoint_auth_methods_supported": ["client_secret_post", "none"],
4289
+ * "authorization_response_iss_parameter_supported": true,
4290
+ * "client_id_metadata_document_supported": true
4291
+ * }
4292
+ * ```
4293
+ * @throws {ValidationError} If `issuer` is not an absolute `https://` URL,
4294
+ * or the document's own `issuer` disagrees with where it was fetched from
4295
+ * (RFC 8414 §3.3 — a mismatch means the document is not authoritative).
4296
+ * @throws {ApiError} If the authorization server rejects the request.
4297
+ *
4298
+ * @example
4299
+ * ```ts
4300
+ * const as = await client.oauth.getAuthorizationServerMetadata();
4301
+ * console.log(as.authorization_endpoint);
4302
+ * ```
4303
+ */
4304
+ getAuthorizationServerMetadata(issuer?: string): Promise<IOAuthAuthorizationServerMetadata>;
4305
+ /**
4306
+ * Mint a PKCE pair and a `state`, then build the consent URL to send the
4307
+ * user's browser to (`GET {authorization_endpoint}`).
4308
+ *
4309
+ * Call this once per connection attempt and keep the whole returned object
4310
+ * in the user's session: reusing a verifier or a `state` across attempts
4311
+ * defeats both PKCE and CSRF protection. Navigate the browser to `url` with
4312
+ * a full page load — an `fetch`/XHR cannot show a consent screen.
4313
+ *
4314
+ * PKCE is mandatory for confidential applications too, and Assinafy accepts
4315
+ * only the `S256` challenge method.
4316
+ *
4317
+ * @param options - Authorization-request options.
4318
+ * @param options.clientId - The application's `client_id`.
4319
+ * @param options.redirectUri - One of the application's registered redirect
4320
+ * URIs, matched character for character (`…/callback` and `…/callback/` are
4321
+ * different). Must be `https://` and carry no fragment.
4322
+ * @param options.scopes - Permissions to request, e.g.
4323
+ * `['documents:read', 'documents:write', 'offline_access']`. Ask for the
4324
+ * minimum: the user approves all of them or none. Add `offline_access` to
4325
+ * receive a refresh token and `openid` to receive an `id_token`.
4326
+ * @param options.authorizationEndpoint - Skip discovery by supplying the
4327
+ * endpoint yourself. Defaults to the discovered
4328
+ * `authorization_endpoint`.
4329
+ * @param options.issuer - Issuer to discover from, and the value the
4330
+ * callback's `iss` must equal. Defaults to the discovered issuer.
4331
+ * @param options.resource - RFC 8707 resource indicator. Defaults to this
4332
+ * API's origin; pass `null` to omit it. It must match the value sent to the
4333
+ * token endpoint, or the exchange fails with `invalid_target`.
4334
+ * @param options.state - Supply your own CSRF value instead of a generated
4335
+ * one. Must be unique per attempt.
4336
+ * @param options.codeVerifier - Supply your own RFC 7636 verifier (43–128
4337
+ * characters from `A-Z a-z 0-9 - . _ ~`) instead of a generated one.
4338
+ * @param options.nonce - OIDC nonce echoed in the `id_token`. Generated
4339
+ * automatically when `openid` is requested; pass a string to set it or
4340
+ * `null` to omit it.
4341
+ * @param options.prompt - Forwarded as the OIDC `prompt` parameter, e.g.
4342
+ * `'consent'` to force the approval screen again.
4343
+ * @returns The request to store and redirect with:
4344
+ * ```jsonc
4345
+ * {
4346
+ * "url": "https://auth.assinafy.com.br/oauth/authorize?response_type=code&client_id=…&redirect_uri=https%3A%2F%2Fmyapp.com%2Foauth%2Fcallback&scope=documents%3Aread+offline_access&state=8Xv…&code_challenge=E9M…&code_challenge_method=S256&resource=https%3A%2F%2Fapi.assinafy.com.br",
4347
+ * "state": "8Xv2rQ7mJt0aLpKcWn4dZg",
4348
+ * "codeVerifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
4349
+ * "issuer": "https://auth.assinafy.com.br",
4350
+ * "nonce": "n-0S6_WzA2Mj"
4351
+ * }
4352
+ * ```
4353
+ * @throws {ValidationError} If `clientId` is empty, `redirectUri` is not an
4354
+ * absolute `https://` URL without a fragment, `scopes` is empty or contains
4355
+ * a value with whitespace, or a supplied `codeVerifier`/`state` is invalid.
4356
+ * @throws {ApiError} If discovery is needed and fails.
4357
+ *
4358
+ * @example
4359
+ * ```ts
4360
+ * const request = await client.oauth.createAuthorizationUrl({
4361
+ * clientId: process.env.ASSINAFY_CLIENT_ID!,
4362
+ * redirectUri: 'https://myapp.com/oauth/callback',
4363
+ * scopes: ['documents:read', 'documents:write', 'offline_access'],
4364
+ * });
4365
+ * session.oauth = request;
4366
+ * response.redirect(request.url);
4367
+ * ```
4368
+ */
4369
+ createAuthorizationUrl(options: {
4370
+ clientId: string;
4371
+ redirectUri: string;
4372
+ scopes: OAuthScope[];
4373
+ authorizationEndpoint?: string;
4374
+ issuer?: string;
4375
+ resource?: string | null;
4376
+ state?: string;
4377
+ codeVerifier?: string;
4378
+ nonce?: string | null;
4379
+ prompt?: string;
4380
+ }): Promise<IOAuthAuthorizationRequest>;
4381
+ /**
4382
+ * Validate the authorization response that lands on your redirect URI and
4383
+ * return the code to exchange.
4384
+ *
4385
+ * Checks, in order and before anything else is trusted: `state` equals the
4386
+ * value from {@link OAuthResource.createAuthorizationUrl} (constant-time),
4387
+ * `iss` is present and equals the expected issuer, and only then whether
4388
+ * the server reported an error. A declined consent arrives as
4389
+ * `?error=access_denied`, not as a failed HTTP request.
4390
+ *
4391
+ * The `iss` check is strict because the authorization server advertises
4392
+ * RFC 9207 support and always sends the parameter: a missing `iss` is
4393
+ * treated exactly like a wrong one. Omit `expected.issuer` only if
4394
+ * something between the browser and your handler strips query parameters.
4395
+ *
4396
+ * This performs no network I/O.
4397
+ *
4398
+ * @param params - The callback's query parameters. Accepts an Express-style
4399
+ * `req.query` record, a `URLSearchParams`, a `URL`, a full callback URL
4400
+ * string, or a bare `a=b&c=d` query string.
4401
+ * @param expected - The stored {@link IOAuthAuthorizationRequest} (or any
4402
+ * object carrying its `state` and `issuer`).
4403
+ * @returns The validated response:
4404
+ * ```jsonc
4405
+ * {
4406
+ * "code": "def50200a1b2c3…",
4407
+ * "state": "8Xv2rQ7mJt0aLpKcWn4dZg",
4408
+ * "issuer": "https://auth.assinafy.com.br"
4409
+ * }
4410
+ * ```
4411
+ * @throws {ValidationError} If `state` is missing or does not match, `iss`
4412
+ * is absent or disagrees with the expected issuer, or a successful response
4413
+ * carries no `code`. In every case the response is not yours — stop, do not
4414
+ * exchange.
4415
+ * @throws {OAuthError} If the server returned `error` (e.g.
4416
+ * `access_denied`, `invalid_scope`, `invalid_request`,
4417
+ * `unsupported_response_type`, `invalid_target`).
4418
+ *
4419
+ * @example
4420
+ * ```ts
4421
+ * app.get('/oauth/callback', async (req, res) => {
4422
+ * const stored = req.session.oauth;
4423
+ * const { code } = client.oauth.readAuthorizationCallback(req.query, stored);
4424
+ * const tokens = await client.oauth.exchangeCode({
4425
+ * code,
4426
+ * codeVerifier: stored.codeVerifier,
4427
+ * redirectUri: 'https://myapp.com/oauth/callback',
4428
+ * clientId: process.env.ASSINAFY_CLIENT_ID!,
4429
+ * clientSecret: process.env.ASSINAFY_CLIENT_SECRET,
4430
+ * });
4431
+ * });
4432
+ * ```
4433
+ */
4434
+ readAuthorizationCallback(params: string | URL | URLSearchParams | Record<string, unknown>, expected: {
4435
+ state: string;
4436
+ issuer?: string;
4437
+ }): IOAuthAuthorizationCallback;
4438
+ /**
4439
+ * Exchange an authorization code for tokens
4440
+ * (`POST /oauth/token`, `grant_type=authorization_code`).
4441
+ *
4442
+ * Run this on your server: the code is single-use and expires **60 seconds**
4443
+ * after approval, and a confidential application's secret must never reach
4444
+ * a browser. Every value must match the authorization request exactly, or
4445
+ * the API answers `invalid_grant`.
4446
+ *
4447
+ * @param options - Exchange options.
4448
+ * @param options.code - The code from
4449
+ * {@link OAuthResource.readAuthorizationCallback}.
4450
+ * @param options.codeVerifier - The verifier stored alongside the request.
4451
+ * @param options.redirectUri - The same redirect URI that was authorized.
4452
+ * @param options.clientId - The application's `client_id`.
4453
+ * @param options.clientSecret - The `client_secret`, for confidential
4454
+ * applications only. Public applications omit it and rely on PKCE.
4455
+ * @param options.resource - The same RFC 8707 resource indicator sent to
4456
+ * the authorization endpoint. Defaults to this API's origin; pass `null` to
4457
+ * omit it. A value disagreeing with the authorized one fails with
4458
+ * `invalid_target`.
4459
+ * @returns The token set — a flat object, **not** the API's usual envelope:
4460
+ * ```jsonc
4461
+ * {
4462
+ * "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…",
4463
+ * "token_type": "Bearer",
4464
+ * "expires_in": 3600,
4465
+ * "scope": "documents:read documents:write",
4466
+ * "refresh_token": "def5020088c2…", // only with offline_access
4467
+ * "id_token": "eyJraWQiOiJEQlR0S0…" // only with openid
4468
+ * }
4469
+ * ```
4470
+ * Read `scope` rather than assuming every requested permission was granted.
4471
+ * @throws {ValidationError} If an argument is missing or malformed, or a
4472
+ * `2xx` response carries no `access_token`.
4473
+ * @throws {OAuthError} `invalid_grant` for a spent, expired, replayed or
4474
+ * mismatched code; `invalid_client` for a bad `client_id`/`client_secret`;
4475
+ * `invalid_target` for a `resource` mismatch.
4476
+ *
4477
+ * @example
4478
+ * ```ts
4479
+ * const tokens = await client.oauth.exchangeCode({
4480
+ * code,
4481
+ * codeVerifier: session.oauth.codeVerifier,
4482
+ * redirectUri: 'https://myapp.com/oauth/callback',
4483
+ * clientId: process.env.ASSINAFY_CLIENT_ID!,
4484
+ * clientSecret: process.env.ASSINAFY_CLIENT_SECRET,
4485
+ * });
4486
+ * ```
4487
+ */
4488
+ exchangeCode(options: TokenEndpointAuthOptions & {
4489
+ code: string;
4490
+ codeVerifier: string;
4491
+ redirectUri: string;
4492
+ resource?: string | null;
4493
+ }): Promise<IOAuthTokenResponse>;
4494
+ /**
4495
+ * Renew an access token (`POST /oauth/token`, `grant_type=refresh_token`).
4496
+ *
4497
+ * Access tokens last one hour; refresh tokens are available only when
4498
+ * `offline_access` was requested and granted.
4499
+ *
4500
+ * **Refresh tokens rotate.** Every call returns a new one and retires the
4501
+ * one you sent, and a replayed refresh token cannot be told apart from a
4502
+ * stolen one — so the server ends the entire connection and the user must
4503
+ * reconnect. Therefore: persist `refresh_token` from the response before
4504
+ * doing anything else with it, treat a timeout as "it may have succeeded"
4505
+ * and re-read your stored token instead of retrying blindly, and never run
4506
+ * two refreshes concurrently for one connection.
4507
+ *
4508
+ * Refreshing does not extend the connection's 30-day life.
4509
+ *
4510
+ * @param options - Refresh options.
4511
+ * @param options.refreshToken - The current refresh token.
4512
+ * @param options.clientId - The application's `client_id`.
4513
+ * @param options.clientSecret - The `client_secret`, for confidential
4514
+ * applications only.
4515
+ * @param options.resource - RFC 8707 resource indicator. Defaults to this
4516
+ * API's origin; pass `null` to omit it.
4517
+ * @returns A fresh token set, identical in shape to
4518
+ * {@link OAuthResource.exchangeCode}:
4519
+ * ```jsonc
4520
+ * {
4521
+ * "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…",
4522
+ * "token_type": "Bearer",
4523
+ * "expires_in": 3600,
4524
+ * "scope": "documents:read documents:write",
4525
+ * "refresh_token": "def50200f1e2…" // NEW — persist it immediately
4526
+ * }
4527
+ * ```
4528
+ * @throws {ValidationError} If an argument is missing, or a `2xx` response
4529
+ * carries no `access_token`.
4530
+ * @throws {OAuthError} `invalid_grant` when the refresh token was already
4531
+ * used, expired, or the user reconnected with different permissions — ask
4532
+ * the user to reconnect. `invalid_client` for bad client credentials.
4533
+ *
4534
+ * @example
4535
+ * ```ts
4536
+ * const tokens = await client.oauth.refreshToken({
4537
+ * refreshToken: connection.refreshToken,
4538
+ * clientId: process.env.ASSINAFY_CLIENT_ID!,
4539
+ * clientSecret: process.env.ASSINAFY_CLIENT_SECRET,
4540
+ * });
4541
+ * await connection.save({ refreshToken: tokens.refresh_token });
4542
+ * ```
4543
+ */
4544
+ refreshToken(options: TokenEndpointAuthOptions & {
4545
+ refreshToken: string;
4546
+ resource?: string | null;
4547
+ }): Promise<IOAuthTokenResponse>;
4548
+ /**
4549
+ * Revoke an access or refresh token (`POST /oauth/revoke`, RFC 7009).
4550
+ *
4551
+ * Call this when a user disconnects your app, instead of only deleting your
4552
+ * copy of the token. Revoking a refresh token ends the whole connection.
4553
+ *
4554
+ * Every token outcome answers `200` — unknown, malformed and
4555
+ * already-revoked included — so the endpoint cannot be used to probe
4556
+ * whether a token exists. Only failed client authentication returns `401`.
4557
+ *
4558
+ * @param options - Revocation options.
4559
+ * @param options.token - The access or refresh token to revoke.
4560
+ * @param options.clientId - The application's `client_id`.
4561
+ * @param options.clientSecret - The `client_secret`, for confidential
4562
+ * applications only.
4563
+ * @param options.tokenTypeHint - Optional `access_token` or
4564
+ * `refresh_token` hint that lets the server skip a lookup.
4565
+ * @returns Nothing; resolves once the API acknowledges the request.
4566
+ * Request body:
4567
+ * ```jsonc
4568
+ * {
4569
+ * "token": "def50200f1e2…",
4570
+ * "token_type_hint": "refresh_token",
4571
+ * "client_id": "cli_1a2b3c",
4572
+ * "client_secret": "…"
4573
+ * }
4574
+ * ```
4575
+ * @throws {ValidationError} If `token` or `clientId` is missing, or
4576
+ * `tokenTypeHint` is not one of the two documented values.
4577
+ * @throws {OAuthError} `invalid_client` when client authentication fails.
4578
+ *
4579
+ * @example
4580
+ * ```ts
4581
+ * await client.oauth.revokeToken({
4582
+ * token: connection.refreshToken,
4583
+ * tokenTypeHint: 'refresh_token',
4584
+ * clientId: process.env.ASSINAFY_CLIENT_ID!,
4585
+ * clientSecret: process.env.ASSINAFY_CLIENT_SECRET,
4586
+ * });
4587
+ * ```
4588
+ */
4589
+ revokeToken(options: TokenEndpointAuthOptions & {
4590
+ token: string;
4591
+ tokenTypeHint?: 'access_token' | 'refresh_token';
4592
+ }): Promise<void>;
4593
+ /**
4594
+ * Read the OpenID Connect claims of the user who authorized a token
4595
+ * (`GET /oauth/userinfo`).
4596
+ *
4597
+ * Requires the `openid` scope; `name` additionally requires `profile` and
4598
+ * `email`/`email_verified` require `email`. Per OIDC Core §5.3.2 the
4599
+ * response is a flat claims object, not this API's usual envelope.
4600
+ *
4601
+ * @param accessToken - Token to introspect. Omit to use the credential the
4602
+ * client was constructed with (`token` or `apiKey`).
4603
+ * @returns The claims the granted scopes allow:
4604
+ * ```jsonc
4605
+ * {
4606
+ * "sub": "d6zqpbyog2v3xvxerwn8la94",
4607
+ * "name": "Maria Silva",
4608
+ * "email": "maria@example.com",
4609
+ * "email_verified": true
4610
+ * }
4611
+ * ```
4612
+ * `sub` is the stable user identifier; the rest are `null` when their scope
4613
+ * was not granted.
4614
+ * @throws {ValidationError} If `accessToken` is supplied but empty.
4615
+ * @throws {ApiError} `401` when the token is missing, expired or revoked;
4616
+ * `403` when the `openid` scope was not granted — its `WWW-Authenticate`
4617
+ * header names the scope to reconnect with.
4618
+ *
4619
+ * @example
4620
+ * ```ts
4621
+ * const who = await client.oauth.getUserInfo(tokens.access_token);
4622
+ * console.log(who.sub, who.email);
4623
+ * ```
4624
+ */
4625
+ getUserInfo(accessToken?: string): Promise<IOAuthUserInfo>;
4626
+ /** POST the token endpoint and assert the response actually carries a token. */
4627
+ private requestToken;
4628
+ /** `client_secret_post` credentials, omitting the secret for public clients. */
4629
+ private clientAuth;
4630
+ /**
4631
+ * Resolve the optional RFC 8707 `resource` indicator.
4632
+ *
4633
+ * Defaults to the configured API origin, which is what this API publishes
4634
+ * as its `resource`. A loopback `http://` base URL — the shape used by mock
4635
+ * servers and the packed-consumer smoke test — has no valid resource
4636
+ * identifier, so the parameter is simply omitted rather than rejected; an
4637
+ * explicitly supplied value is still required to be `https`.
4638
+ */
4639
+ private resourceParam;
4640
+ /** Discover which authorization server may issue tokens for this API. */
4641
+ private defaultIssuer;
4642
+ /**
4643
+ * Origin of the configured API host.
4644
+ *
4645
+ * The `.well-known` document and the RFC 8707 resource indicator both sit
4646
+ * at the host root, while `baseUrl` points at `/v1`.
4647
+ */
4648
+ private apiOrigin;
4649
+ }
4650
+
3991
4651
  /**
3992
4652
  * Custom field definitions used by `collect` assignments.
3993
4653
  *
@@ -5038,6 +5698,7 @@ declare class AssinafyClient {
5038
5698
  readonly templates: TemplateResource;
5039
5699
  readonly tags: TagResource;
5040
5700
  readonly auth: AuthenticationResource;
5701
+ readonly oauth: OAuthResource;
5041
5702
  readonly fields: FieldsResource;
5042
5703
  readonly signerDocuments: SignerDocumentsResource;
5043
5704
  readonly users: UserResource;
@@ -5255,6 +5916,40 @@ declare class AssinafyClient {
5255
5916
  getAxiosInstance(): AxiosInstance;
5256
5917
  }
5257
5918
 
5919
+ /**
5920
+ * One parsed `WWW-Authenticate` challenge.
5921
+ *
5922
+ * Assinafy answers an OAuth request that is missing a scope with
5923
+ * `403` and `WWW-Authenticate: Bearer error="insufficient_scope",
5924
+ * scope="documents:write", resource_metadata="…"`. `scope` names the permission
5925
+ * to request on the next authorization round-trip, so the challenge is the only
5926
+ * machine-readable way to tell "reconnect asking for more" apart from "this
5927
+ * token can never reach that surface".
5928
+ */
5929
+ interface IAuthenticateChallenge {
5930
+ /** Authentication scheme, e.g. `Bearer`. */
5931
+ scheme: string;
5932
+ /** RFC 6750 error code, e.g. `insufficient_scope` or `invalid_token`. */
5933
+ error?: string;
5934
+ /** Human-readable explanation, when the server sends one. */
5935
+ error_description?: string;
5936
+ /** Space-separated scopes required by the rejected operation. */
5937
+ scope?: string;
5938
+ /** RFC 9728 URL of the protected-resource metadata document. */
5939
+ resource_metadata?: string;
5940
+ }
5941
+ /**
5942
+ * Parse a `WWW-Authenticate` header into its scheme and auth-param map.
5943
+ *
5944
+ * Only the first challenge is read: Assinafy sends exactly one, and a parser
5945
+ * that split on commas would corrupt quoted values containing them.
5946
+ *
5947
+ * @param value - Raw header value, or `undefined` when absent.
5948
+ * @returns The parsed challenge, or `undefined` when there is no header or it
5949
+ * carries no scheme.
5950
+ */
5951
+ declare function parseWwwAuthenticate(value: string | undefined): IAuthenticateChallenge | undefined;
5952
+
5258
5953
  /** Base class for all Assinafy SDK errors. */
5259
5954
  declare class AssinafyError extends Error {
5260
5955
  readonly context: Record<string, unknown>;
@@ -5276,6 +5971,29 @@ declare class AssinafyError extends Error {
5276
5971
  declare class ApiError extends AssinafyError {
5277
5972
  readonly statusCode: number;
5278
5973
  readonly responseData: unknown;
5974
+ /**
5975
+ * Parsed `WWW-Authenticate` challenge, when the response carried one.
5976
+ *
5977
+ * A `403` whose challenge is `{ error: 'insufficient_scope', scope: '…' }`
5978
+ * means the OAuth token is valid but was never granted that permission:
5979
+ * send the user through the authorization flow again asking for the scope
5980
+ * named in `scope`. A `403` without a challenge has a different cause —
5981
+ * another workspace, the user's role, or a surface OAuth tokens never
5982
+ * reach — and reconnecting will not fix it.
5983
+ *
5984
+ * @example
5985
+ * ```ts
5986
+ * try {
5987
+ * await connected.documents.upload({ filePath: './contract.pdf' });
5988
+ * } catch (error) {
5989
+ * if (error instanceof ApiError && error.challenge?.error === 'insufficient_scope') {
5990
+ * return reconnect(error.challenge.scope); // 'documents:write'
5991
+ * }
5992
+ * throw error;
5993
+ * }
5994
+ * ```
5995
+ */
5996
+ challenge?: IAuthenticateChallenge;
5279
5997
  /**
5280
5998
  * Create an error representing a non-success API response.
5281
5999
  *
@@ -5306,6 +6024,59 @@ declare class ApiError extends AssinafyError {
5306
6024
  */
5307
6025
  static fromResponse(statusCode: number, responseData: unknown): ApiError;
5308
6026
  }
6027
+ /**
6028
+ * Thrown when an OAuth endpoint returns an RFC 6749 error object, or when an
6029
+ * authorization response comes back on the redirect URI carrying `?error=`.
6030
+ *
6031
+ * The OAuth endpoints answer with a flat `{ error, error_description }` body
6032
+ * instead of this API's `{ status, message, data }` envelope, because no
6033
+ * standard OAuth client would look for `error` inside a `data` key. This class
6034
+ * still extends {@link ApiError}, so existing `catch (err) { if (err instanceof
6035
+ * ApiError) … }` blocks keep matching.
6036
+ *
6037
+ * Branch on {@link OAuthError.error}, not on the message:
6038
+ *
6039
+ * | `error` | What to do |
6040
+ * | --- | --- |
6041
+ * | `invalid_grant` | The code or refresh token is spent, expired, or bound to other parameters. Send the user through the authorization flow again. |
6042
+ * | `invalid_client` | Wrong `client_id`/`client_secret`, or the application was disabled. Fix the configuration; retrying will not help. |
6043
+ * | `invalid_target` | The `resource` does not match the one that was authorized. |
6044
+ * | `unsupported_grant_type` | Only `authorization_code` and `refresh_token` exist. |
6045
+ * | `access_denied` | The user declined on the consent screen. |
6046
+ * | `invalid_scope` | A scope the application is not registered for. |
6047
+ * | `invalid_request` | Missing or malformed PKCE / request parameters. |
6048
+ */
6049
+ declare class OAuthError extends ApiError {
6050
+ /** RFC 6749 error code, e.g. `invalid_grant`. */
6051
+ readonly error: string;
6052
+ /** The server's human-readable explanation, when it sent one. */
6053
+ readonly errorDescription: string | null;
6054
+ /**
6055
+ * Create an OAuth protocol error.
6056
+ *
6057
+ * @param error - RFC 6749 error code.
6058
+ * @param errorDescription - Server-provided explanation, or `null`.
6059
+ * @param statusCode - HTTP status that carried it. Authorization responses
6060
+ * arrive as redirect query parameters rather than an HTTP response, so
6061
+ * {@link OAuthResource.readAuthorizationCallback} reports them as `400`.
6062
+ * @param responseData - The raw error object.
6063
+ *
6064
+ * @example
6065
+ * ```ts
6066
+ * throw new OAuthError('invalid_grant', 'Authorization code expired.', 400);
6067
+ * ```
6068
+ */
6069
+ constructor(error: string, errorDescription?: string | null, statusCode?: number, responseData?: unknown);
6070
+ /**
6071
+ * Upgrade an {@link ApiError} to an {@link OAuthError} when its body is an
6072
+ * RFC 6749 error object; otherwise return the value untouched.
6073
+ *
6074
+ * @param error - Any thrown value.
6075
+ * @returns An `OAuthError` when the body carries a non-empty string
6076
+ * `error`, else the original value.
6077
+ */
6078
+ static upgrade(error: unknown): unknown;
6079
+ }
5309
6080
  /** Thrown when SDK validation fails, including invalid input or workflow state. */
5310
6081
  declare class ValidationError extends AssinafyError {
5311
6082
  readonly errors: Record<string, unknown>;
@@ -5349,4 +6120,4 @@ declare const MAX_LIST_PAGE_SIZE = 50;
5349
6120
 
5350
6121
  declare const SDK_USER_AGENT: string;
5351
6122
 
5352
- export { type AccountLogoUploadSource, type AnyString, ApiError, type AssignmentDisplaySettings, type AssignmentMethod, type AssignmentNotificationMethod, AssignmentResource, type AssignmentVerificationMethod, AssinafyClient, type AssinafyClientOptions, AssinafyError, AuthenticationResource, type ClientConfigInput, DEFAULT_WEBHOOK_EVENTS, type DocumentArtifactName, DocumentResource, type DocumentStatsGranularity, type DocumentStatus, type DocumentUploadSource, FieldsResource, type IAccountTheme, type IApiKeyResponse, type IAssignment, type IAssignmentCostSigner, type IAssignmentEntry, type IAssignmentItem, type IAssignmentListParams, type IAssignmentListResponse, type IAssignmentSigner, type IAuthenticatedUser, type IConfirmSignerDataPayload, type ICostEstimate, type ICreateAssignmentPayload, type ICreateAssignmentResponse, type ICreateDocumentFromTemplateOptions, type ICreateFieldPayload, type ICreateSignerPayload, type ICreateSignerResponse, type ICreateTagPayload, type ICreateWorkspacePayload, type IDeleteTagResponse, type IDetachDocumentTagResponse, type IDisplaySettings, type IDocumentActivity, type IDocumentDetailsResponse, type IDocumentListItem, type IDocumentListParams, type IDocumentListResponse, type IDocumentSearchParams, type IDocumentStatsParams, type IDocumentStatsRow, type IDocumentStatusInfo, type IDocumentUploadOptions, type IDocumentUploadResponse, type IDocumentVerification, type IEstimateAssignmentCostPayload, type IFieldDefinition, type IFieldType, type IFieldValidateMultipleEntry, type IFieldValidationMultipleResult, type IFieldValidationResponse, type IFieldValidationResult, type IInlineTag, type ILegacyConfirmSignerDataPayload, type ILegacyResendCostEstimate, type ILegacyUploadSignatureOptions, type IListParams, type ILoginResponse, type IMaskedApiKeyResponse, type INotificationHistoryEntry, type INotificationPreferences, type IPage, type IPaginatedResponse, type IPublicDocumentInfo, type IRenameDocumentResponse, type IResendCostEstimate, type IResendEmailResponse, type ISignFieldEntry, type ISigner, type ISignerListParams, type ISignerListResponse, type ISignerSelf, type ISigningProgress, type ITag, type ITemplateCostSigner, type ITemplateDetailsResponse, type ITemplateFieldPlacement, type ITemplateListItem, type ITemplateListParams, type ITemplateListResponse, type ITemplateRole, type ITemplateSigner, type IUpdateFieldPayload, type IUpdateNotificationPreferences, type IUpdateSignerPayload, type IUpdateTagPayload, type IUpdateTemplatePayload, type IUpdateWorkspacePayload, type IUploadAndRequestSignaturesResult, type IUploadAndRequestSignaturesSigner, type IUploadSignatureOptions, type IWebhookDispatch, type IWebhookDispatchListParams, type IWebhookEventTypeInfo, type IWebhookPayload, type IWebhookRegisterPayload, type IWebhookSubscription, type IWhatsAppNotification, type IWorkspaceListItem, type IWorkspaceListResponse, type IWorkspaceResponse, type Logger, MAX_LIST_PAGE_SIZE, MAX_UPLOAD_BYTES, NetworkError, type NotificationSenderType, type PaginatedResult, type PaginationMeta, SDK_USER_AGENT, type SendTokenChannel, type SignatureImageType, SignerDocumentsResource, type SignerReference, SignerResource, TagResource, TemplateResource, UserResource, ValidationError, type WebhookEventType, WebhookResource, WebhookVerifier, WorkspaceResource, buildAssignmentPayload };
6123
+ export { type AccountLogoUploadSource, type AnyString, ApiError, type AssignmentDisplaySettings, type AssignmentMethod, type AssignmentNotificationMethod, AssignmentResource, type AssignmentVerificationMethod, AssinafyClient, type AssinafyClientOptions, AssinafyError, AuthenticationResource, type ClientConfigInput, DEFAULT_WEBHOOK_EVENTS, type DocumentArtifactName, DocumentResource, type DocumentStatsGranularity, type DocumentStatus, type DocumentUploadSource, FieldsResource, type IAccountTheme, type IApiKeyResponse, type IAssignment, type IAssignmentCostSigner, type IAssignmentEntry, type IAssignmentItem, type IAssignmentListParams, type IAssignmentListResponse, type IAssignmentSigner, type IAuthenticateChallenge, type IAuthenticatedUser, type IConfirmSignerDataPayload, type ICostEstimate, type ICreateAssignmentPayload, type ICreateAssignmentResponse, type ICreateDocumentFromTemplateOptions, type ICreateFieldPayload, type ICreateSignerPayload, type ICreateSignerResponse, type ICreateTagPayload, type ICreateWorkspacePayload, type IDeleteTagResponse, type IDetachDocumentTagResponse, type IDisplaySettings, type IDocumentActivity, type IDocumentDetailsResponse, type IDocumentListItem, type IDocumentListParams, type IDocumentListResponse, type IDocumentSearchParams, type IDocumentStatsParams, type IDocumentStatsRow, type IDocumentStatusInfo, type IDocumentUploadOptions, type IDocumentUploadResponse, type IDocumentVerification, type IEstimateAssignmentCostPayload, type IFieldDefinition, type IFieldType, type IFieldValidateMultipleEntry, type IFieldValidationMultipleResult, type IFieldValidationResponse, type IFieldValidationResult, type IInlineTag, type ILegacyConfirmSignerDataPayload, type ILegacyResendCostEstimate, type ILegacyUploadSignatureOptions, type IListParams, type ILoginResponse, type IMaskedApiKeyResponse, type INotificationHistoryEntry, type INotificationPreferences, type IOAuthAuthorizationCallback, type IOAuthAuthorizationRequest, type IOAuthAuthorizationServerMetadata, type IOAuthProtectedResourceMetadata, type IOAuthTokenResponse, type IOAuthUserInfo, type IPage, type IPaginatedResponse, type IPublicDocumentInfo, type IRenameDocumentResponse, type IResendCostEstimate, type IResendEmailResponse, type ISignFieldEntry, type ISigner, type ISignerListParams, type ISignerListResponse, type ISignerSelf, type ISigningProgress, type ITag, type ITemplateCostSigner, type ITemplateDetailsResponse, type ITemplateFieldPlacement, type ITemplateListItem, type ITemplateListParams, type ITemplateListResponse, type ITemplateRole, type ITemplateSigner, type IUpdateFieldPayload, type IUpdateNotificationPreferences, type IUpdateSignerPayload, type IUpdateTagPayload, type IUpdateTemplatePayload, type IUpdateWorkspacePayload, type IUploadAndRequestSignaturesResult, type IUploadAndRequestSignaturesSigner, type IUploadSignatureOptions, type IWebhookDispatch, type IWebhookDispatchListParams, type IWebhookEventTypeInfo, type IWebhookPayload, type IWebhookRegisterPayload, type IWebhookSubscription, type IWhatsAppNotification, type IWorkspaceListItem, type IWorkspaceListResponse, type IWorkspaceResponse, type Logger, MAX_LIST_PAGE_SIZE, MAX_UPLOAD_BYTES, NetworkError, type NotificationSenderType, OAuthError, OAuthResource, type OAuthScope, type PaginatedResult, type PaginationMeta, SDK_USER_AGENT, type SendTokenChannel, type SignatureImageType, SignerDocumentsResource, type SignerReference, SignerResource, TagResource, TemplateResource, UserResource, ValidationError, type WebhookEventType, WebhookResource, WebhookVerifier, WorkspaceResource, buildAssignmentPayload, parseWwwAuthenticate };