@alvera-ai/platform-sdk 0.21.2 → 0.21.3-next.g393d024
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/.agent/AGENTS.md +11 -18
- package/.agent/action_logs.md +2 -2
- package/.agent/action_status_updaters.md +63 -6
- package/.agent/async.md +4 -4
- package/.agent/cookbook/_fixtures/README.md +28 -32
- package/.agent/cookbook/organic-marketing.md +0 -5
- package/.agent/cookbook/payments-compliance.md +0 -10
- package/.agent/cookbook/primary-care.md +0 -5
- package/.agent/cookbook/subscription-saas.md +0 -8
- package/.agent/datalakes.md +2 -2
- package/.agent/errors.md +32 -6
- package/.agent/interoperability_contracts.md +4 -7
- package/.agent/mdm.md +165 -81
- package/.agent/tools.md +5 -1
- package/dist/index.d.mts +17 -30
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +16 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/.agent/mdm.md
CHANGED
|
@@ -41,8 +41,8 @@ vocabulary — `given_name`, `family_name`, `birth_date` and
|
|
|
41
41
|
`gender` are gone, not renamed variants to pick between.
|
|
42
42
|
|
|
43
43
|
```
|
|
44
|
-
MDMVerifyRequest every field the
|
|
45
|
-
────────────────
|
|
44
|
+
MDMVerifyRequest every field the request takes
|
|
45
|
+
──────────────── ─────────────────────────────
|
|
46
46
|
required legal_entity_id
|
|
47
47
|
individual first_name middle_name last_name
|
|
48
48
|
preferred_name date_of_birth
|
|
@@ -53,6 +53,18 @@ vocabulary — `given_name`, `family_name`, `birth_date` and
|
|
|
53
53
|
identifiers addresses
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
Not every field is evidence on its own (§2):
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
can stand alone first_name last_name preferred_name
|
|
60
|
+
date_of_birth business_name date_formed
|
|
61
|
+
phone identifiers addresses
|
|
62
|
+
only beside one legal_entity_type middle_name
|
|
63
|
+
of those citizenship_country nationality
|
|
64
|
+
doing_business_as_names
|
|
65
|
+
jurisdiction_country email
|
|
66
|
+
```
|
|
67
|
+
|
|
56
68
|
An individual example:
|
|
57
69
|
|
|
58
70
|
```typescript
|
|
@@ -88,24 +100,56 @@ const { data: result } = await api.mdm.verify(
|
|
|
88
100
|
],
|
|
89
101
|
},
|
|
90
102
|
)
|
|
91
|
-
// result.status
|
|
103
|
+
// result.status === 'verified' — the only success body
|
|
92
104
|
// result.legal_entity_id === body.legal_entity_id
|
|
93
|
-
// result.verified_at
|
|
94
|
-
// when status === 'not_verified':
|
|
95
|
-
// result.errors — { <field_name>: [reason, ...] } per-field failure detail
|
|
105
|
+
// result.verified_at — ISO 8601 timestamp
|
|
96
106
|
```
|
|
97
107
|
|
|
98
|
-
|
|
108
|
+
`verified` is the **only** success body. A subject that does not
|
|
109
|
+
verify is not a body you read — the call throws, like every other
|
|
110
|
+
route that answers 4xx:
|
|
99
111
|
|
|
100
112
|
```
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
verified → 200 { status: 'verified', legal_entity_id, verified_at }
|
|
114
|
+
did not verify → throws AlveraApiError, _httpStatus 422
|
|
115
|
+
{ errors: [ { title: 'Invalid value',
|
|
116
|
+
source: { pointer: '/<field>' },
|
|
117
|
+
detail: '<why it failed>' } ] }
|
|
118
|
+
one entry per field that did not match
|
|
119
|
+
subject not found → throws AlveraApiError, _httpStatus 404
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
So `data` is only ever the verified answer, and every failed check
|
|
123
|
+
reaches you in `catch`, in the same envelope every other 422 uses
|
|
124
|
+
(see `errors.md`). Read which fields failed from each entry's
|
|
125
|
+
`source.pointer`:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import type { AlveraApiError } from '@alvera-ai/platform-sdk'
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
const { data } = await api.mdm.verify(tenantSlug, datalakeSlug, {
|
|
132
|
+
legal_entity_id: '00000000-0000-0000-0000-000000000000',
|
|
133
|
+
last_name: 'Garcia',
|
|
134
|
+
addresses: [{ postal_code: '94110', country: 'US' }],
|
|
135
|
+
})
|
|
136
|
+
// data.status === 'verified' — act on this person
|
|
137
|
+
} catch (err) {
|
|
138
|
+
const status = (err as { _httpStatus?: number })._httpStatus
|
|
139
|
+
if (status === 422) {
|
|
140
|
+
for (const e of (err as AlveraApiError).errors) {
|
|
141
|
+
// e.source.pointer — '/last_name', '/addresses', '/base', …
|
|
142
|
+
// e.detail — 'does not match any known name', …
|
|
143
|
+
}
|
|
144
|
+
} else if (status === 404) {
|
|
145
|
+
// no legal entity has this id
|
|
146
|
+
} else {
|
|
147
|
+
throw err
|
|
148
|
+
}
|
|
149
|
+
}
|
|
103
150
|
```
|
|
104
151
|
|
|
105
|
-
A
|
|
106
|
-
returned a negative result — it arrives as a 422 whose body
|
|
107
|
-
still carries the full envelope. Distinguish it from the other
|
|
108
|
-
rejections (404 for missing subject, 401 for missing auth).
|
|
152
|
+
A 401 (missing or wrong key) throws too.
|
|
109
153
|
|
|
110
154
|
### One subject: the legal entity
|
|
111
155
|
|
|
@@ -128,14 +172,23 @@ declare the column; every generic-table row struct already has it.
|
|
|
128
172
|
|
|
129
173
|
## 2. Rules the type cannot encode
|
|
130
174
|
|
|
131
|
-
### `legal_entity_id` is required; at least one
|
|
175
|
+
### `legal_entity_id` is required; at least one field that stands alone with it
|
|
132
176
|
|
|
133
177
|
`legal_entity_id` (the master record to verify against) is the
|
|
134
178
|
only required field. Every other property is optional, and the
|
|
135
|
-
verifier requires **at least one
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
179
|
+
verifier requires **at least one field that can stand alone as
|
|
180
|
+
evidence** at runtime: `first_name`, `last_name`, `preferred_name`,
|
|
181
|
+
`date_of_birth`, `business_name`, `date_formed`, `phone`,
|
|
182
|
+
`identifiers` or `addresses`. The other seven (`legal_entity_type`,
|
|
183
|
+
`middle_name`, `citizenship_country`, `nationality`,
|
|
184
|
+
`doing_business_as_names`, `jurisdiction_country`, `email`) are
|
|
185
|
+
accepted, but count only beside one of those nine.
|
|
186
|
+
|
|
187
|
+
- a body with only `legal_entity_id`, or with only fields from the
|
|
188
|
+
seven → 422, one entry with `source.pointer: '/base'` and
|
|
189
|
+
`detail: 'at least one verification field is required'`
|
|
190
|
+
- an address alone is enough evidence; if it does not match, the
|
|
191
|
+
422 carries the `/addresses` entry and nothing else
|
|
139
192
|
|
|
140
193
|
A body carrying the retired vocabulary — `given_name`,
|
|
141
194
|
`family_name`, `birth_date`, `gender` — falls into that same 422,
|
|
@@ -160,9 +213,33 @@ addresses per-component exact, case- and whitespace-
|
|
|
160
213
|
insensitive; at least one address must match
|
|
161
214
|
```
|
|
162
215
|
|
|
163
|
-
All supplied fields must pass for the
|
|
164
|
-
`'verified'`.
|
|
165
|
-
|
|
216
|
+
All supplied fields must pass for the call to return
|
|
217
|
+
`'verified'`. Each field that fails adds one entry to the thrown
|
|
218
|
+
422, pointing at the field you sent:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
source.pointer detail
|
|
222
|
+
/last_name does not match any known name
|
|
223
|
+
/first_name does not match any known name (see below)
|
|
224
|
+
/business_name does not match any known name
|
|
225
|
+
/date_of_birth does not match
|
|
226
|
+
/date_formed does not match
|
|
227
|
+
/identifiers no matching identifier found
|
|
228
|
+
/phone does not match any known phone number
|
|
229
|
+
/addresses no matching address found
|
|
230
|
+
/addresses/country can't be blank (an address sent without a country)
|
|
231
|
+
/base at least one verification field is required
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
First, middle and preferred names are checked together as one
|
|
235
|
+
bag of given names, so they fail as one entry. It points at a
|
|
236
|
+
given-name field you actually sent: `/first_name` if you sent one,
|
|
237
|
+
else `/middle_name`, else `/preferred_name`.
|
|
238
|
+
|
|
239
|
+
Two fields failing is two entries; nothing is summarised into a
|
|
240
|
+
single verdict. The mock answers its wrong-details case with one
|
|
241
|
+
`/base` entry, `detail: 'Verification match failed'`; the platform
|
|
242
|
+
itself names the field.
|
|
166
243
|
|
|
167
244
|
### `legal_entity_id` is the legal entity's own id
|
|
168
245
|
|
|
@@ -176,11 +253,12 @@ redacted lakes — rather than a second row with its own id. The
|
|
|
176
253
|
old failure mode where passing the regulated twin's id returned a
|
|
177
254
|
404 cannot arise.
|
|
178
255
|
|
|
179
|
-
If the supplied `legal_entity_id` doesn't resolve, the
|
|
180
|
-
|
|
256
|
+
If the supplied `legal_entity_id` doesn't resolve, the call throws
|
|
257
|
+
a 404 envelope (`title: 'Not Found'`, `detail: 'Subject not found'`,
|
|
258
|
+
empty `source.pointer`), not a 422. The distinction matters:
|
|
181
259
|
|
|
182
|
-
-
|
|
183
|
-
- 404
|
|
260
|
+
- 422 -> "entity exists, identity fields didn't match"
|
|
261
|
+
- 404 -> "entity doesn't exist at all"
|
|
184
262
|
|
|
185
263
|
A consumer that conflates the two will mis-route an identity
|
|
186
264
|
challenge as a missing-record error.
|
|
@@ -245,13 +323,14 @@ Two limits that follow from the same rule:
|
|
|
245
323
|
**Server-derived (Response-only).**
|
|
246
324
|
|
|
247
325
|
```
|
|
248
|
-
status enum — 'verified'
|
|
249
|
-
verified_at string — ISO 8601 timestamp of the verification
|
|
250
|
-
errors object — present only when status === 'not_verified';
|
|
251
|
-
maps field name to an array of failure reasons
|
|
326
|
+
status enum — 'verified', its only value
|
|
327
|
+
verified_at string — ISO 8601 timestamp of the verification
|
|
252
328
|
```
|
|
253
329
|
|
|
254
|
-
|
|
330
|
+
There is no `errors` field on the response: a failed check is a
|
|
331
|
+
thrown 422 (§4), never a body.
|
|
332
|
+
|
|
333
|
+
**Caller-supplied (round-trip in the verified answer).**
|
|
255
334
|
|
|
256
335
|
```
|
|
257
336
|
legal_entity_id required UUID — the master record to verify against
|
|
@@ -270,35 +349,35 @@ legal_entity_id required UUID — the master record to verify against
|
|
|
270
349
|
|
|
271
350
|
## 4. Error envelopes
|
|
272
351
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
|
278
|
-
|
|
279
|
-
|
|
|
280
|
-
| `/
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
352
|
+
Every error `.verify` returns is the standard JSON:API envelope
|
|
353
|
+
per `errors.md`, thrown as `AlveraApiError`. There is no second
|
|
354
|
+
shape. Common rejections:
|
|
355
|
+
|
|
356
|
+
| HTTP | `source.pointer` | Cause |
|
|
357
|
+
|------|---------------------------|-------|
|
|
358
|
+
| 422 | `/<field>` | a field you sent did not match the master record — one entry per field (§2 lists the pointers and details) |
|
|
359
|
+
| 422 | `/base` | no field that can stand alone as evidence was supplied (§2) — including a body of only `email`, `middle_name` or the other five that count only beside one, or only retired fields (`given_name`, `family_name`, `birth_date`, `gender`), which are ignored |
|
|
360
|
+
| 422 | `/legal_entity_id` | `legal_entity_id` missing from the body |
|
|
361
|
+
| 422 | `/identifiers/0/system` | missing system on an identifier entry |
|
|
362
|
+
| 422 | `/identifiers/0/value` | missing value on an identifier entry |
|
|
363
|
+
| 404 | `""` (empty) | no legal entity has this id — `title: 'Not Found'`, `detail: 'Subject not found'` |
|
|
364
|
+
|
|
365
|
+
A subject that does not verify and a body the platform refuses
|
|
366
|
+
arrive the same way: a 422 whose entries all carry
|
|
367
|
+
`title: 'Invalid value'`. Read the field from `source.pointer`.
|
|
368
|
+
There is no `errors` map keyed by field name, and a failure body
|
|
369
|
+
carries no `status`, `legal_entity_id` or `verified_at`.
|
|
370
|
+
|
|
371
|
+
`system` and `value` on an identifier are required by the request
|
|
372
|
+
schema, so a missing one is refused before verification runs, and
|
|
373
|
+
its pointer carries the entry's index. An embed the verifier
|
|
374
|
+
itself rejects points at the embed's field without an index: an
|
|
375
|
+
address sent without a country is `/addresses/country`, not
|
|
376
|
+
`/addresses/0/country`. `id_type` and `country` on an identifier
|
|
377
|
+
are optional. Either way it is a 422, never a 500.
|
|
378
|
+
|
|
379
|
+
Branch on `_httpStatus`: 422 for a failed check or a refused body,
|
|
380
|
+
404 for a subject that does not exist (§6 gotcha 2).
|
|
302
381
|
|
|
303
382
|
## 5. Lifecycle
|
|
304
383
|
|
|
@@ -344,26 +423,30 @@ through `api.mdm`.
|
|
|
344
423
|
|
|
345
424
|
## 6. Gotchas
|
|
346
425
|
|
|
347
|
-
1. **
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
`
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
426
|
+
1. **A subject that does not verify throws; there is no
|
|
427
|
+
`not_verified` body.** `data` is only ever the verified answer.
|
|
428
|
+
Every failed check is a thrown `AlveraApiError` with
|
|
429
|
+
`_httpStatus === 422`, one entry per mismatched field. Code
|
|
430
|
+
written for the old `{ status: 'not_verified', errors: {…} }`
|
|
431
|
+
body never runs: its branch is unreachable and the 422 lands in
|
|
432
|
+
`catch`. Don't let generic 4xx handling swallow it — read each
|
|
433
|
+
entry's `source.pointer` to learn which fields failed.
|
|
434
|
+
|
|
435
|
+
2. **Subject missing → 404, identity mismatch → 422.** Both
|
|
436
|
+
throw, in the same envelope. A verify call against a deleted
|
|
437
|
+
or never-existed entity id throws a 404 (`title: 'Not Found'`,
|
|
438
|
+
empty pointer), not a 422. Branch on `_httpStatus` before
|
|
439
|
+
reading pointers, per `errors.md`.
|
|
440
|
+
|
|
441
|
+
3. **At least one field that can stand alone is required.** A body
|
|
442
|
+
with only `legal_entity_id` — or only fields that count just
|
|
443
|
+
beside another (`email`, `middle_name`, `nationality`, …), or
|
|
444
|
+
only retired fields like `given_name` or `birth_date`, which are
|
|
445
|
+
ignored — throws a 422 with one
|
|
446
|
+
entry: `source.pointer: '/base'`, `detail: 'at least one
|
|
447
|
+
verification field is required'`. This is enforced at runtime
|
|
448
|
+
rather than in the request schema, so the TypeScript type
|
|
449
|
+
permits the body but the wire rejects it.
|
|
367
450
|
|
|
368
451
|
4. **Unknown fields are ignored, not rejected.** There is one
|
|
369
452
|
field set (§1) and no domain scoping, but anything outside it
|
|
@@ -385,8 +468,9 @@ through `api.mdm`.
|
|
|
385
468
|
case, and trailing slashes in `system` URIs all matter.
|
|
386
469
|
Compare with the master record's identifier system strings
|
|
387
470
|
character-for-character; a `'http://hospital.org/mrn'` vs
|
|
388
|
-
`'http://hospital.org/mrn/'` mismatch
|
|
389
|
-
|
|
471
|
+
`'http://hospital.org/mrn/'` mismatch fails the check with an
|
|
472
|
+
`/identifiers` entry (`no matching identifier found`) even when
|
|
473
|
+
the value is correct.
|
|
390
474
|
`system` and `value` are the required pair. `id_type`
|
|
391
475
|
(`'digital_identifier'`, `'us_ssn'`, `'lei'`) and `country`
|
|
392
476
|
are optional — the per-domain rule that once made `id_type`
|
package/.agent/tools.md
CHANGED
|
@@ -792,12 +792,16 @@ the ASU's AI metadata. A failed poll lands its structured reason in
|
|
|
792
792
|
You do **not** have to wait for the cron. `actionStatusUpdaters.refresh`
|
|
793
793
|
fires one poll cycle on demand (CLI: `alvera refresh-action-status-updater
|
|
794
794
|
--id <uuid>`), and reading `last_run_*` correctly is what makes it
|
|
795
|
-
usable as a proof —
|
|
795
|
+
usable as a proof — four things to get right:
|
|
796
796
|
|
|
797
797
|
- **`refresh` answers `202` with the updater row AS-IS.** The poll runs
|
|
798
798
|
asynchronously, so the response carries the PREVIOUS run's stamps.
|
|
799
799
|
Capture `last_run_at` as a baseline BEFORE calling it, then poll the
|
|
800
800
|
row until `last_run_at` advances past that baseline.
|
|
801
|
+
- **`refresh` can answer `409` and queue nothing.** A halted updater
|
|
802
|
+
(`status` not `'active'`) refuses until you set `status` back to
|
|
803
|
+
`'active'`. An updater with a poll already queued or running refuses
|
|
804
|
+
until that poll finishes; retry then. The error's `detail` says which.
|
|
801
805
|
- **`last_run_status` has two values.** `'ok'` means the run read its
|
|
802
806
|
whole time window; `'error'` means it stopped, and `last_run_error`
|
|
803
807
|
says why. There is no partial run: every page of the window is read,
|
package/dist/index.d.mts
CHANGED
|
@@ -690,6 +690,10 @@ type ActionStatusUpdaterResponse = {
|
|
|
690
690
|
* Outcome of the last poll run: `ok` when the run read its whole window, `error` when it stopped — read `last_run_error` for why. A run is never partial: every page of the window is read, one job per page.
|
|
691
691
|
*/
|
|
692
692
|
readonly last_run_status?: 'ok' | 'error';
|
|
693
|
+
/**
|
|
694
|
+
* When a cron tick last skipped because an earlier run of this updater was still going (null if none has). A skip is not a run and leaves the last-run fields alone.
|
|
695
|
+
*/
|
|
696
|
+
readonly last_skipped_at?: string | null;
|
|
693
697
|
message_config: SimpleTemplateConfigResponse;
|
|
694
698
|
/**
|
|
695
699
|
* Updater name
|
|
@@ -999,21 +1003,20 @@ declare enum ActionType {
|
|
|
999
1003
|
*
|
|
1000
1004
|
* Every legal entity is ultimately a **person** or a **company**, so the identity
|
|
1001
1005
|
* fields are organized along that ontology rather than per industry. All identity
|
|
1002
|
-
* fields are optional on the wire
|
|
1003
|
-
* only the fields its domain knows and requires **at least one** of them — a body
|
|
1004
|
-
* that carries only fields foreign to the datalake's domain (or none at all)
|
|
1005
|
-
* returns 422 with `errors.base: ["at least one verification field is required"]`.
|
|
1006
|
+
* fields are optional on the wire, and every datalake reads the same set.
|
|
1006
1007
|
*
|
|
1007
|
-
*
|
|
1008
|
+
* At least one field that can stand alone as evidence is required: `first_name`,
|
|
1009
|
+
* `last_name`, `preferred_name`, `date_of_birth`, `business_name`, `date_formed`,
|
|
1010
|
+
* `phone`, `identifiers` or `addresses`. The rest (`legal_entity_type`,
|
|
1011
|
+
* `middle_name`, `citizenship_country`, `nationality`, `doing_business_as_names`,
|
|
1012
|
+
* `jurisdiction_country`, `email`) are accepted but cannot be the only evidence.
|
|
1013
|
+
* A body with none returns 422 in the house error envelope, pointer `/base`.
|
|
1008
1014
|
*
|
|
1009
|
-
*
|
|
1010
|
-
*
|
|
1011
|
-
*
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1014
|
-
* `@verification_fields`. Keep the two in step — a property advertised here
|
|
1015
|
-
* but absent there is accepted by the router and then silently dropped by
|
|
1016
|
-
* `cast/3`, which reads to the caller as "my attribute did not match".
|
|
1015
|
+
* Every property below is cast by `Platform.MDMInput.verification_changeset/2`:
|
|
1016
|
+
* `@verification_fields` plus the `identifiers` and `addresses` embeds. Keep the
|
|
1017
|
+
* two in step — a property advertised here but absent there is accepted by the
|
|
1018
|
+
* router and then silently dropped by `cast/3`, which reads to the caller as "my
|
|
1019
|
+
* attribute did not match".
|
|
1017
1020
|
*
|
|
1018
1021
|
*/
|
|
1019
1022
|
type MdmVerifyRequest = {
|
|
@@ -3324,7 +3327,7 @@ type SqlDatabaseResponse = {
|
|
|
3324
3327
|
/**
|
|
3325
3328
|
* MDMVerifyResponse
|
|
3326
3329
|
*
|
|
3327
|
-
*
|
|
3330
|
+
* A legal entity that verified against its master record
|
|
3328
3331
|
*/
|
|
3329
3332
|
type MdmVerifyResponse = {
|
|
3330
3333
|
/**
|
|
@@ -3336,22 +3339,6 @@ type MdmVerifyResponse = {
|
|
|
3336
3339
|
* Timestamp of verification
|
|
3337
3340
|
*/
|
|
3338
3341
|
verified_at: string;
|
|
3339
|
-
} | {
|
|
3340
|
-
/**
|
|
3341
|
-
* Field-level verification failure details
|
|
3342
|
-
*/
|
|
3343
|
-
errors: {
|
|
3344
|
-
[key: string]: Array<string>;
|
|
3345
|
-
};
|
|
3346
|
-
/**
|
|
3347
|
-
* The legal entity id that failed verification
|
|
3348
|
-
*/
|
|
3349
|
-
legal_entity_id: string;
|
|
3350
|
-
status: 'not_verified';
|
|
3351
|
-
/**
|
|
3352
|
-
* Timestamp of verification attempt
|
|
3353
|
-
*/
|
|
3354
|
-
verified_at: string;
|
|
3355
3342
|
};
|
|
3356
3343
|
/**
|
|
3357
3344
|
* S3CloudStorageAwsResponse
|