Developer guide

Why use applications?

Applications represent ID.me’s managed configurations for customer services (web apps, mobile apps, physical locations, etc.) that interact with ID.me. Once an application is created, you receive a unique UUID that can be attached to your interactions with ID.me. This enables application-level interaction tracking and reporting, providing visibility into which specific applications are driving traffic, conversions, and user behavior. Additional use cases and capabilities may be added in the future.

API specifications

API specifications are not publicly available. Please contact your account manager or solution consultant to obtain detailed integration specifications.

API endpoints

Creating an application

POST /v1/organizations/{organizationUuid}/applications

Returns the created application object including the generated UUID.

Applications are created under a specific organization. You must provide the organization’s UUID in the path. The application creation requires several fields including the application name, status, class, and claimant UUID. The API validates conditional field dependencies. For example, certain architecture and platform fields are only valid when the application class is “digital”.

Key requirements

  • Organization UUID is required in the path
  • Required fields: name, status, class, claimantUuid
  • Optional fields: type, subtype, architectureType, operatingSystem, deviceTypes, consumerUuid, userTypes
    • Field values:
      ValueDefinition
      nameDefined by the user
      claimantUuidThe UUID of an existing organization that defines which organization the application belongs to. This can be the organizationUuid provided in the request path or the UUID of another organization (for example, ID.me itself), depending on the ownership model.
      consumerUuidThe consumerUuid field is optional and is only required in specific migration scenarios. If provided, include the UUID when creating the application. Most external integrations do not need to supply this value.

All other fields are enums with predefined values. Conditional input validation applies based on field dependencies (see Enums section below). Call the enums API to get possible values.

Retrieving a single application

GET /v1/applications/{applicationUuid}

Returns the application object with all attributes.

Retrieve detailed information about a specific application using its UUID. The API enforces authorization. Users must have access to the application’s parent organization. If the user lacks access, a 404 response is returned to prevent enumeration.

Key requirements

  • Application UUID is required in the path
  • User must have read access to the application’s organization

Retrieving applications for an organization

GET /v1/organizations/{organizationUuid}/applications

Returns an array of application objects (empty array if none exist).

Retrieve all applications that belong to a specific organization. This is useful when you need to list or audit all applications under an organization. Authorization is enforced at the organization level.

Key requirements

  • Organization UUID is required in the path
  • User must have access to the specified organization

Updating an application

PATCH /v1/applications/{applicationUuid}

Returns the updated application object.

Partially update an existing application using PATCH semantics. Only the fields provided in the request body will be modified. This endpoint is commonly used to update application status, including soft deletion.

Key requirements

  • Application UUID is required in the path
  • Only updatable fields can be modified: status, class, type, subtype, architectureType, operatingSystem, deviceTypes, userTypes
  • Immutable fields: name, organizationUuid, claimantUuid, consumerUuid
  • The same conditional validation rules apply as during creation
  • User must have access to the application’s organization

Soft deletion

To soft delete an application, use PATCH to change the application’s status to an inactive or deleted status value.

The application will be marked as inactive but a record will remain in the system for historical tracking and reporting purposes.

Getting enum values

GET /v1/applications/enums

Returns an array of valid enum values as strings, sorted alphabetically.

This endpoint returns the valid enum values for application attributes. You must use these values when creating or updating an application, as the API validates all enum fields against the allowed values.

Query parameters

ParameterDescriptionRequired
enum_nameThe enum type to retrieve status, class, type, subtype, architectureType, operatingSystem, deviceTypesYes
classRequired when retrieving type, subtype, architectureType, operatingSystem, or deviceTypesConditional
typeRequired when retrieving subtypeConditional
architecture_typeRequired when retrieving operatingSystemConditional

Field dependencies

The enum values have hierarchical dependencies that reflect the following conditional validation rules:

TypeDependenciesNote
statusNoneCan be queried directly
classNoneCan be queried directly
typeclassDifferent types are available for different classes
subtypeclass and typeSubtypes vary by application type
architectureTypeclassOnly valid for certain classes
operatingSystemarchitectureTypeOnly certain architecture types have operating system options
deviceTypesclassOnly valid for certain classes

These dependencies ensure that applications are created with valid and consistent attribute combinations. For example, you cannot specify an operating system unless the application architecture type supports it.

Always perform a GET /v1/applications/enums to retrieve the latest enum values

Example process

The following demonstrates a typical process and how the endpoints work together.

1

Get available enum values

Use GET to retrieve the enum values you’ll need for creating an application.

GET example
1# Get available statuses
2GET /v1/applications/enums?enum_name=status
3Response: ["active", "inactive", ...]
4
5# Get available classes
6GET /v1/applications/enums?enum_name=class
7Response: ["digital", "physical", ...]
8
9# Get types for digital class
10GET /v1/applications/enums?enum_name=type&class=digital
11Response: ["web", "mobile", ...]
12
13# Get architecture types (assuming class=digital was determined)
14GET /v1/applications/enums?enum_name=architectureType&class=digital
15Response: ["native", "web", ...]
2

Create the application

Using the enum values from step one, use POST to create a new application.

POST example
1POST /v1/organizations/550e8400-e29b-41d4-a716-446655440000/applications
2{
3 "name": "Mobile Banking App",
4 "status": "active",
5 "class": "digital",
6 "type": "mobile",
7 "architectureType": "native",
8 "claimantUuid": "123e4567-e89b-12d3-a456-426614174000",
9 "userTypes": ["personal", "business"]
10}
11
12Response: {
13 "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
14 "name": "Mobile Banking App",
15 "status": "active",
16 ...
17}
Important

Save the UUID. You will need this to attach to your interactions with ID.me.

3

Retrieve applications for the organization

Use GET to verify the application was created and view all applications for the organization.

GET example
1GET /v1/organizations/550e8400-e29b-41d4-a716-446655440000/applications
2
3Response: [
4 {
5 "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
6 "name": "Mobile Banking App",
7 "status": "active",
8 ...
9 },
10 ...
11]
4

Soft delete the application

If an application is no longer in use, you can use PATCH to soft delete it by updating its status.

PATCH example
1PATCH /v1/applications/7c9e6679-7425-40de-944b-e07fc1f90ae7
2{
3 "status": "inactive"
4}
5
6Response: {
7 "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
8 "name": "Mobile Banking App",
9 "status": "inactive",
10 ...
11}

The application will be marked as inactive but a record will remain in the system for historical tracking and reporting purposes.

Additional notes

  • All endpoints require proper authentication (access token for external usage and JWT for internal usage)
  • UUID formats are validated for all UUID parameters
  • Conditional field validation ensures data consistency across related attributes
  • The enums endpoint should be consulted when building forms or validation logic to ensure submitted values are current

AI agent

If you are utilizing an AI agent to assist with writing the API client, please copy the JSON below, then provide it to your agent.

Use the Copy to clipboard button located on the top-right side of the code block

Organizations API agent guide
1{
2 "api_metadata": {
3 "name": "Organizations API",
4 "version": "2025-11-06.trust",
5 "protocol": "REST",
6 "spec_version": "OpenAPI 3.0.4",
7 "base_url": "CONFIGURE_PER_ENVIRONMENT",
8 "description": "API for managing organizations, applications, domains, and jurisdictions with OAuth2 authentication",
9 "auth_type": "OAuth2"
10 },
11 "authentication": {
12 "how_to_get_access_token": {
13 "step_1": "Create a new account from https://developer.id.me",
14 "step_2": "Create a new organization or pick an existing one",
15 "step_3": "Create a new application or pick an existing one, click on Verification Dashboard and click Continue",
16 "step_4": "Obtain the [client_id] and [client_secret] for that application",
17 "step_5": "Send HTTP request to get access token",
18 "request_example": {
19 "url": "https://api.id.me/oauth/token",
20 "method": "POST",
21 "headers": {
22 "Content-Type": "application/x-www-form-urlencoded"
23 },
24 "body": {
25 "grant_type": "client_credentials",
26 "client_id": "[client_id]",
27 "client_secret": "[client_secret]",
28 "aud": "[aud_value_based_on_endpoint]",
29 "scope": "[required_scopes_space_separated]"
30 }
31 },
32 "response_example": {
33 "access_token": "token_string",
34 "token_type": "bearer",
35 "expires_in": 300,
36 "scope": "organizations:read organizations:write"
37 }
38 },
39 "oauth2_scopes": {
40 "organizations:read": {
41 "description": "Read organization data",
42 "required_for": [
43 "GET /v1/organizations",
44 "GET /v1/organizations/{uuid}",
45 "GET /v1/organizations/{uuid}/domains",
46 "GET /v1/jurisdictions/countries",
47 "GET /v1/jurisdictions/subdivisions",
48 "GET /v1/jurisdictions/autocomplete",
49 "GET /v1/sectors",
50 "GET /v1/sectors/{id}/structures"
51 ],
52 "aud": "organizations-api"
53 },
54 "organizations:write": {
55 "description": "Create and update organizations",
56 "required_for": [
57 "POST /v1/organizations",
58 "PATCH /v1/organizations/{uuid}"
59 ],
60 "aud": "organizations-api"
61 },
62 "applications:read": {
63 "description": "Read application data",
64 "required_for": [
65 "GET /v1/organizations/{organizationUuid}/applications",
66 "GET /v1/applications/{applicationUuid}",
67 "GET /v1/applications/enums"
68 ],
69 "aud": "organizations-api"
70 },
71 "applications:write": {
72 "description": "Create and update applications",
73 "required_for": [
74 "POST /v1/organizations/{organizationUuid}/applications",
75 "PATCH /v1/applications/{applicationUuid}"
76 ],
77 "aud": "organizations-api"
78 },
79 "domains:read": {
80 "description": "Read domain data",
81 "required_for": [
82 "GET /v1/domains/{domain}"
83 ],
84 "aud": "organizations-api"
85 },
86 "domains:write": {
87 "description": "Create and validate domains",
88 "required_for": [
89 "POST /v1/domains"
90 ],
91 "aud": "organizations-api"
92 }
93 }
94 },
95 "critical_rules": {
96 "match_keys": {
97 "rule": "ALL_OR_NOTHING",
98 "description": "If any match key is provided, ALL match keys must be provided or the API will return 422 error",
99 "fields": [
100 "legalName",
101 "organizationSector",
102 "organizationStructure",
103 "jurisdictionOfFormation"
104 ],
105 "error_if_incomplete": 422,
106 "error_message": "All match keys must be provided if any match key is specified"
107 },
108 "jurisdiction_formats": {
109 "description": "Format requirements for jurisdictionOfFormation based on sector and structure",
110 "Private": {
111 "format": "ISO_3166_2",
112 "example": "US-CA",
113 "description": "State/province level (e.g., US-CA for California)"
114 },
115 "Non-profit": {
116 "format": "ISO_3166_2",
117 "example": "CA-ON",
118 "description": "State/province level (e.g., CA-ON for Ontario)"
119 },
120 "Public-Federal": {
121 "format": "ISO_3166_1",
122 "example": "US",
123 "description": "Country level (e.g., US or USA)"
124 },
125 "Public-State": {
126 "format": "ISO_3166_2",
127 "example": "US-OH",
128 "description": "State level (e.g., US-OH for Ohio)"
129 },
130 "Public-District": {
131 "format": "ISO_3166_2",
132 "example": "US-OH",
133 "description": "State level (e.g., US-OH for Ohio)"
134 },
135 "Public-County": {
136 "format": "ISO_3166_2_PLUS_DISTRICT",
137 "example": "US-OH-Franklin",
138 "description": "State + District name (e.g., US-OH-Franklin for Franklin County)"
139 },
140 "Public-City": {
141 "format": "ISO_3166_2_PLUS_MUNICIPALITY",
142 "example": "US-OH-Columbus",
143 "description": "State + Municipality name (e.g., US-OH-Columbus for Columbus city)"
144 },
145 "Public-Other": {
146 "format": "ISO_3166_1",
147 "example": "US",
148 "description": "Country level (e.g., US or USA)"
149 }
150 },
151 "application_constraints": {
152 "channel": {
153 "rule": "ONLY_IF_class_equals_digital",
154 "description": "channel field can only be provided when class is 'digital'",
155 "valid_values": [
156 "spa",
157 "web",
158 "native",
159 "service"
160 ]
161 },
162 "operating_system": {
163 "rule": "ONLY_IF_channel_equals_native",
164 "description": "operating_system field can only be provided when channel is 'native'",
165 "valid_values": [
166 "ios",
167 "android",
168 "chromeos",
169 "windows",
170 "macos",
171 "linux"
172 ]
173 },
174 "deviceTypes": {
175 "rule": "ONLY_IF_class_equals_digital",
176 "description": "deviceTypes field can only be provided when class is 'digital'",
177 "valid_values": [
178 "mobile",
179 "desktop"
180 ]
181 },
182 "userTypes": {
183 "rule": "MUST_NOT_BE_EMPTY",
184 "description": "userTypes array must contain at least one value",
185 "valid_values": [
186 "personal",
187 "business"
188 ]
189 },
190 "enum_validation": {
191 "rule": "USE_ENUMS_ENDPOINT_FOR_VALID_VALUES",
192 "description": "All enum values (status, class, type, subtype, architectureType, operatingSystem, deviceTypes) must be fetched from GET /v1/applications/enums endpoint",
193 "critical_note": "Not all class+type+subtype combinations are valid. The database enforces valid combinations via application_class_type_to_subtype mapping table",
194 "validation_behavior": {
195 "on_create": "If subtype is provided without type, returns 400. If class+type+subtype combination is invalid, returns 422.",
196 "on_update": "Same validation as create. Invalid combinations are rejected."
197 },
198 "recommendation": "Use the hierarchical enum fetching workflow documented in GET /v1/applications/enums endpoint to ensure only valid combinations are presented to users"
199 }
200 },
201 "idempotency": {
202 "create_organization": {
203 "behavior": "RETURNS_EXISTING_IF_MATCH_KEYS_MATCH",
204 "description": "If an organization with matching legalName, organizationSector, organizationStructure, and jurisdictionOfFormation already exists, the existing organization is returned instead of creating a new one"
205 }
206 },
207 "patch_restrictions": {
208 "non_updatable_fields": [
209 "legalName",
210 "organizationSector",
211 "organizationStructure",
212 "jurisdictionOfFormation",
213 "uuid",
214 "createdAt"
215 ],
216 "description": "These fields cannot be updated via PATCH requests. Match keys are immutable to maintain organization identity."
217 },
218 "domain_normalization": {
219 "description": "Domain names are automatically normalized: converted to lowercase, trimmed, and registerable domain extracted",
220 "example": "https://www.Example.COM/ becomes example.com"
221 },
222 "address_validation": {
223 "required_fields": [
224 "number",
225 "subdivisionIso2",
226 "countryIso2"
227 ],
228 "description": "When providing addresses (primaryAddress or officeAddress), these fields are required"
229 }
230 },
231 "data_types": {
232 "Organization": {
233 "description": "Represents a legal entity (business, government agency, or non-profit)",
234 "fields": {
235 "uuid": {
236 "type": "string",
237 "format": "uuid",
238 "auto_generated": true,
239 "immutable": true,
240 "description": "Globally unique organization identifier"
241 },
242 "legalName": {
243 "type": "string",
244 "required": true,
245 "immutable_via_patch": true,
246 "description": "The full legal name of the organization (e.g., Acme, Inc.)"
247 },
248 "organizationSector": {
249 "type": "string",
250 "enum": [
251 "Public",
252 "Private",
253 "Non-profit"
254 ],
255 "required": true,
256 "immutable_via_patch": true,
257 "case_sensitive": true,
258 "description": "The sector of the economy that the organization belongs to"
259 },
260 "organizationStructure": {
261 "type": "string",
262 "required": true,
263 "immutable_via_patch": true,
264 "description": "The legal and operational structure (e.g., Corporation, LLC, State Agency)",
265 "note": "Valid values depend on organizationSector - use GET /v1/sectors/{id}/structures to get valid values"
266 },
267 "jurisdictionOfFormation": {
268 "type": "string",
269 "format": "iso_code",
270 "required": true,
271 "immutable_via_patch": true,
272 "description": "ISO-based jurisdiction code where the organization was formed",
273 "note": "Format varies by sector and structure - see jurisdiction_formats in critical_rules"
274 },
275 "claimant": {
276 "type": "string",
277 "format": "uuid",
278 "required": true,
279 "description": "UUID of the user or organization claiming this organization"
280 },
281 "claimantType": {
282 "type": "string",
283 "enum": [
284 "USER",
285 "ORGANIZATION"
286 ],
287 "default": "USER",
288 "case_sensitive": true,
289 "description": "Type of the claimant entity"
290 },
291 "domains": {
292 "type": "array",
293 "items": "string",
294 "readonly": true,
295 "description": "List of validated domains associated with this organization"
296 },
297 "logoUrl": {
298 "type": "string",
299 "format": "uri",
300 "optional": true,
301 "updatable": true,
302 "description": "URL to organization logo"
303 },
304 "doingBusinessAsNames": {
305 "type": "array",
306 "items": "string",
307 "optional": true,
308 "updatable": true,
309 "description": "Array of 'doing business as' names (DBAs)"
310 },
311 "dateOfFormation": {
312 "type": "string",
313 "format": "YYYY-MM-DD",
314 "optional": true,
315 "updatable": true,
316 "description": "Date of organization formation"
317 },
318 "ein": {
319 "type": "string",
320 "optional": true,
321 "updatable": true,
322 "description": "Employer Identification Number"
323 },
324 "duns": {
325 "type": "string",
326 "optional": true,
327 "updatable": true,
328 "description": "DUNS number"
329 },
330 "uei": {
331 "type": "string",
332 "optional": true,
333 "updatable": true,
334 "description": "Unique Entity Identifier"
335 },
336 "primaryAddress": {
337 "type": "Address",
338 "optional": true,
339 "updatable": true,
340 "description": "Primary business address"
341 },
342 "officeAddress": {
343 "type": "Address",
344 "optional": true,
345 "updatable": true,
346 "description": "Office address"
347 },
348 "validationStatus": {
349 "type": "string",
350 "enum": [
351 "PENDING",
352 "COMPLETED"
353 ],
354 "auto_generated": true,
355 "default": "PENDING",
356 "description": "Status of the organization's validation by Attribute Validation Service"
357 },
358 "createdAt": {
359 "type": "string",
360 "format": "iso8601",
361 "auto_generated": true,
362 "immutable": true,
363 "description": "Creation timestamp"
364 },
365 "updatedAt": {
366 "type": "string",
367 "format": "iso8601",
368 "auto_generated": true,
369 "description": "Last modification timestamp"
370 }
371 }
372 },
373 "Address": {
374 "description": "Physical address structure",
375 "fields": {
376 "number": {
377 "type": "string",
378 "required": true,
379 "description": "Street number"
380 },
381 "street": {
382 "type": "string",
383 "required": true,
384 "description": "Street name"
385 },
386 "street2": {
387 "type": "string",
388 "optional": true,
389 "description": "Additional street information (suite, apartment, etc.)"
390 },
391 "municipality": {
392 "type": "string",
393 "required": true,
394 "description": "City or municipality name"
395 },
396 "subdivisionIso2": {
397 "type": "string",
398 "format": "iso2",
399 "required": true,
400 "description": "State/province ISO2 code (e.g., CA for California)"
401 },
402 "postalCode": {
403 "type": "string",
404 "required": true,
405 "description": "Postal/ZIP code"
406 },
407 "countryIso2": {
408 "type": "string",
409 "format": "iso2",
410 "required": true,
411 "description": "Country ISO2 code (e.g., US for United States)"
412 }
413 }
414 },
415 "Application": {
416 "description": "Represents a software application or physical entity within an organization",
417 "fields": {
418 "uuid": {
419 "type": "string",
420 "format": "uuid",
421 "auto_generated": true,
422 "immutable": true,
423 "description": "Globally unique application identifier"
424 },
425 "name": {
426 "type": "string",
427 "required": true,
428 "unique_within": "organization",
429 "description": "Application name (must be unique within organization)"
430 },
431 "status": {
432 "type": "string",
433 "enum": [
434 "active",
435 "deprecated",
436 "inactive",
437 "closed"
438 ],
439 "required": true,
440 "description": "Application lifecycle status"
441 },
442 "class": {
443 "type": "string",
444 "enum": [
445 "digital",
446 "physical"
447 ],
448 "required": true,
449 "description": "Application class - determines which conditional fields are allowed"
450 },
451 "type": {
452 "type": "string",
453 "enum": [
454 "Self-Service",
455 "Assisted Service",
456 "Machine",
457 "Internal Operations"
458 ],
459 "optional": true,
460 "description": "Application type"
461 },
462 "subtype": {
463 "type": "string",
464 "optional": true,
465 "depends_on": [
466 "class",
467 "type"
468 ],
469 "description": "Application subtype - valid values depend on class and type mapping"
470 },
471 "channel": {
472 "type": "string",
473 "enum": [
474 "spa",
475 "web",
476 "native",
477 "service"
478 ],
479 "conditional": "class==digital",
480 "description": "Application channel - only valid when class is 'digital'"
481 },
482 "operating_system": {
483 "type": "string",
484 "enum": [
485 "ios",
486 "android",
487 "chromeos",
488 "windows",
489 "macos",
490 "linux"
491 ],
492 "conditional": "channel==native",
493 "description": "Operating system - only valid when channel is 'native'"
494 },
495 "deviceTypes": {
496 "type": "array",
497 "items": {
498 "enum": [
499 "mobile",
500 "desktop"
501 ]
502 },
503 "conditional": "class==digital",
504 "description": "Device types - only valid when class is 'digital'"
505 },
506 "userTypes": {
507 "type": "array",
508 "items": {
509 "enum": [
510 "personal",
511 "business"
512 ]
513 },
514 "required": true,
515 "min_length": 1,
516 "description": "User types for the application - must contain at least one value"
517 },
518 "organizationUuid": {
519 "type": "string",
520 "format": "uuid",
521 "auto_from_path": true,
522 "description": "UUID of the organization this application belongs to"
523 },
524 "claimantUuid": {
525 "type": "string",
526 "format": "uuid",
527 "required": true,
528 "description": "UUID of an existing organization that will be the claimant"
529 },
530 "consumerUuid": {
531 "type": "string",
532 "format": "uuid",
533 "optional": true,
534 "description": "Consumer UUID"
535 }
536 }
537 },
538 "Domain": {
539 "description": "Represents a domain name and its validation/registration data",
540 "fields": {
541 "domainName": {
542 "type": "string",
543 "required": true,
544 "normalized": true,
545 "description": "Domain name (automatically normalized to lowercase)"
546 },
547 "organizationUuid": {
548 "type": "string",
549 "format": "uuid",
550 "description": "UUID of the organization that owns this domain (after validation)"
551 },
552 "validationSource": {
553 "type": "string",
554 "description": "Source of domain validation (RDAP or WHOIS)"
555 },
556 "registrantName": {
557 "type": "string",
558 "description": "Domain registrant name from RDAP/WHOIS"
559 },
560 "registrar": {
561 "type": "string",
562 "description": "Domain registrar from RDAP/WHOIS"
563 },
564 "registry": {
565 "type": "string",
566 "description": "Domain registry from RDAP/WHOIS"
567 },
568 "registeredAt": {
569 "type": "string",
570 "format": "iso8601",
571 "description": "Domain registration date"
572 },
573 "expiresAt": {
574 "type": "string",
575 "format": "iso8601",
576 "description": "Domain expiration date"
577 }
578 }
579 },
580 "Country": {
581 "description": "Country reference data",
582 "fields": {
583 "id": {
584 "type": "integer",
585 "description": "Internal country ID"
586 },
587 "name": {
588 "type": "string",
589 "description": "Country name"
590 },
591 "iso2": {
592 "type": "string",
593 "length": 2,
594 "description": "ISO 3166-1 alpha-2 code"
595 },
596 "iso3": {
597 "type": "string",
598 "length": 3,
599 "description": "ISO 3166-1 alpha-3 code"
600 },
601 "phoneCountryCode": {
602 "type": "string",
603 "description": "Phone country code"
604 },
605 "createdAt": {
606 "type": "string",
607 "format": "iso8601"
608 },
609 "updatedAt": {
610 "type": "string",
611 "format": "iso8601"
612 }
613 }
614 },
615 "Subdivision": {
616 "description": "State/province subdivision reference data",
617 "fields": {
618 "id": {
619 "type": "integer",
620 "description": "Internal subdivision ID"
621 },
622 "countryId": {
623 "type": "integer",
624 "description": "Foreign key to country"
625 },
626 "name": {
627 "type": "string",
628 "description": "Subdivision name (e.g., California, Ontario)"
629 },
630 "code": {
631 "type": "string",
632 "format": "iso_3166_2",
633 "description": "ISO 3166-2 subdivision code (e.g., US-CA)"
634 },
635 "createdAt": {
636 "type": "string",
637 "format": "iso8601"
638 },
639 "updatedAt": {
640 "type": "string",
641 "format": "iso8601"
642 }
643 }
644 },
645 "Sector": {
646 "description": "Organization sector reference data",
647 "fields": {
648 "id": {
649 "type": "integer",
650 "description": "Internal sector ID"
651 },
652 "name": {
653 "type": "string",
654 "enum": [
655 "Public",
656 "Private",
657 "Non-profit"
658 ],
659 "description": "Sector name"
660 },
661 "createdAt": {
662 "type": "string",
663 "format": "iso8601"
664 },
665 "updatedAt": {
666 "type": "string",
667 "format": "iso8601"
668 }
669 }
670 },
671 "Structure": {
672 "description": "Organization structure reference data (depends on sector)",
673 "fields": {
674 "id": {
675 "type": "integer",
676 "description": "Internal structure ID"
677 },
678 "sectorId": {
679 "type": "integer",
680 "description": "Foreign key to sector"
681 },
682 "name": {
683 "type": "string",
684 "description": "Structure name (e.g., Corporation, LLC, Federal, State Agency)"
685 },
686 "createdAt": {
687 "type": "string",
688 "format": "iso8601"
689 },
690 "updatedAt": {
691 "type": "string",
692 "format": "iso8601"
693 }
694 }
695 },
696 "PlacesAutocompleteResponse": {
697 "description": "Response from Google Places API autocomplete",
698 "fields": {
699 "data": {
700 "type": "array",
701 "items": "AutocompletePrediction",
702 "description": "Array of autocomplete predictions (up to 5)"
703 }
704 }
705 },
706 "AutocompletePrediction": {
707 "description": "Single autocomplete prediction",
708 "fields": {
709 "type": {
710 "type": "string",
711 "value": "autocomplete-prediction",
712 "description": "Type identifier"
713 },
714 "attributes": {
715 "type": "PredictionAttributes",
716 "description": "Prediction details"
717 }
718 }
719 },
720 "PredictionAttributes": {
721 "description": "Attributes of autocomplete prediction",
722 "fields": {
723 "formattedAddress": {
724 "type": "string",
725 "description": "Full formatted address"
726 },
727 "municipality": {
728 "type": "string",
729 "description": "City name (can be empty string)"
730 },
731 "district": {
732 "type": "string",
733 "description": "County/district name (can be empty string)"
734 },
735 "subdivision": {
736 "type": "string",
737 "description": "State/province name (can be empty string)"
738 },
739 "country": {
740 "type": "string",
741 "format": "iso2",
742 "description": "Country ISO2 code"
743 }
744 }
745 }
746 },
747 "endpoints": [
748 {
749 "id": "create_organization",
750 "method": "POST",
751 "path": "/v1/organizations",
752 "scope": "organizations:write",
753 "aud": "organizations-api",
754 "description": "Creates a new organization with the provided details. Returns existing organization if match keys already exist (idempotent).",
755 "request_body": {
756 "required": true,
757 "content_type": "application/json",
758 "required_fields": [
759 "claimant",
760 "legalName",
761 "organizationSector",
762 "organizationStructure",
763 "jurisdictionOfFormation"
764 ],
765 "optional_fields": [
766 "claimantType",
767 "logoUrl",
768 "doingBusinessAsNames",
769 "dateOfFormation",
770 "ein",
771 "duns",
772 "uei",
773 "primaryAddress",
774 "officeAddress"
775 ]
776 },
777 "responses": {
778 "201": {
779 "description": "Organization created or existing organization returned",
780 "type": "Organization"
781 },
782 "400": {
783 "description": "Bad Request - validation error"
784 },
785 "401": {
786 "description": "Unauthorized - invalid or missing token"
787 },
788 "404": {
789 "description": "Not Found - referenced entity not found"
790 },
791 "422": {
792 "description": "Unprocessable Entity - incomplete match keys"
793 },
794 "500": {
795 "description": "Internal Server Error"
796 }
797 }
798 },
799 {
800 "id": "search_organizations",
801 "method": "GET",
802 "path": "/v1/organizations",
803 "scope": "organizations:read",
804 "aud": "organizations-api",
805 "description": "Search organizations by filters (match keys or domain). All parameters are optional. Default limit is 100.",
806 "query_params": {
807 "legal_name": {
808 "type": "string",
809 "optional": true,
810 "description": "Organization legal name"
811 },
812 "sector": {
813 "type": "string",
814 "enum": [
815 "Public",
816 "Private",
817 "Non-profit"
818 ],
819 "optional": true
820 },
821 "structure": {
822 "type": "string",
823 "optional": true,
824 "description": "Organization structure"
825 },
826 "jurisdiction_of_formation": {
827 "type": "string",
828 "format": "iso_code",
829 "optional": true,
830 "example": "US-CA"
831 },
832 "domain": {
833 "type": "string",
834 "optional": true,
835 "description": "Returns organization that controls this domain (only validated relationships)",
836 "example": "testorg.net"
837 },
838 "user_id": {
839 "type": "string",
840 "optional": true,
841 "description": "Filter organizations by user access (Developer Portal use)"
842 },
843 "limit": {
844 "type": "integer",
845 "default": 100,
846 "optional": true,
847 "description": "Number of items to return"
848 },
849 "sort_by": {
850 "type": "string",
851 "default": "legal_name",
852 "optional": true,
853 "description": "Field to sort by. Prepend with '-' for descending order"
854 }
855 },
856 "responses": {
857 "200": {
858 "description": "Array of organizations matching filters",
859 "type": "array",
860 "items": "Organization"
861 },
862 "400": {
863 "description": "Bad Request"
864 },
865 "401": {
866 "description": "Unauthorized"
867 },
868 "500": {
869 "description": "Internal Server Error"
870 }
871 }
872 },
873 {
874 "id": "get_organization_by_id",
875 "method": "GET",
876 "path": "/v1/organizations/{uuid}",
877 "scope": "organizations:read",
878 "aud": "organizations-api",
879 "description": "Retrieve a single organization by UUID",
880 "path_params": {
881 "uuid": {
882 "type": "string",
883 "format": "uuid",
884 "required": true,
885 "description": "Organization UUID"
886 }
887 },
888 "query_params": {
889 "user_id": {
890 "type": "string",
891 "optional": true,
892 "description": "User ID for access control (Developer Portal use)"
893 }
894 },
895 "responses": {
896 "200": {
897 "description": "Organization details",
898 "type": "Organization"
899 },
900 "400": {
901 "description": "Bad Request"
902 },
903 "401": {
904 "description": "Unauthorized"
905 },
906 "403": {
907 "description": "Forbidden - user does not have access to this organization"
908 },
909 "404": {
910 "description": "Not Found - organization does not exist"
911 },
912 "500": {
913 "description": "Internal Server Error"
914 }
915 }
916 },
917 {
918 "id": "update_organization",
919 "method": "PATCH",
920 "path": "/v1/organizations/{uuid}",
921 "scope": "organizations:write",
922 "aud": "organizations-api",
923 "description": "Partially update an organization using PATCH semantics. Only provided fields are updated. Match keys CANNOT be updated.",
924 "path_params": {
925 "uuid": {
926 "type": "string",
927 "format": "uuid",
928 "required": true,
929 "description": "Organization UUID"
930 }
931 },
932 "request_body": {
933 "required": true,
934 "content_type": "application/json",
935 "all_fields_optional": true,
936 "updatable_fields": [
937 "logoUrl",
938 "doingBusinessAsNames",
939 "dateOfFormation",
940 "ein",
941 "duns",
942 "uei",
943 "primaryAddress",
944 "officeAddress"
945 ],
946 "non_updatable_fields": [
947 "legalName",
948 "organizationSector",
949 "organizationStructure",
950 "jurisdictionOfFormation",
951 "uuid",
952 "createdAt"
953 ]
954 },
955 "responses": {
956 "200": {
957 "description": "Updated organization",
958 "type": "Organization"
959 },
960 "400": {
961 "description": "Bad Request - validation error"
962 },
963 "401": {
964 "description": "Unauthorized"
965 },
966 "403": {
967 "description": "Forbidden - user must have admin role for organization"
968 },
969 "404": {
970 "description": "Not Found - organization does not exist"
971 },
972 "500": {
973 "description": "Internal Server Error"
974 }
975 }
976 },
977 {
978 "id": "get_organization_domains",
979 "method": "GET",
980 "path": "/v1/organizations/{uuid}/domains",
981 "scope": "organizations:read",
982 "aud": "organizations-api",
983 "description": "Retrieve list of domains associated with an organization",
984 "path_params": {
985 "uuid": {
986 "type": "string",
987 "format": "uuid",
988 "required": true,
989 "description": "Organization UUID"
990 }
991 },
992 "responses": {
993 "200": {
994 "description": "Array of domain names",
995 "type": "array",
996 "items": "string"
997 },
998 "400": {
999 "description": "Bad Request"
1000 },
1001 "401": {
1002 "description": "Unauthorized"
1003 },
1004 "404": {
1005 "description": "Not Found"
1006 },
1007 "500": {
1008 "description": "Internal Server Error"
1009 }
1010 }
1011 },
1012 {
1013 "id": "create_application",
1014 "method": "POST",
1015 "path": "/v1/organizations/{organization_uuid}/applications",
1016 "scope": "applications:write",
1017 "aud": "organizations-api",
1018 "description": "Create a new application within an organization. Validates conditional field requirements based on class.",
1019 "path_params": {
1020 "organization_uuid": {
1021 "type": "string",
1022 "format": "uuid",
1023 "required": true,
1024 "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
1025 "description": "Organization UUID"
1026 }
1027 },
1028 "request_body": {
1029 "required": true,
1030 "content_type": "application/json",
1031 "required_fields": [
1032 "name",
1033 "status",
1034 "class",
1035 "userTypes",
1036 "claimantUuid"
1037 ],
1038 "optional_fields": [
1039 "type",
1040 "subtype",
1041 "channel",
1042 "operating_system",
1043 "deviceTypes",
1044 "consumerUuid"
1045 ],
1046 "conditional_fields": {
1047 "channel": "Only valid when class='digital'",
1048 "operating_system": "Only valid when channel='native'",
1049 "deviceTypes": "Only valid when class='digital'"
1050 }
1051 },
1052 "responses": {
1053 "201": {
1054 "description": "Application created successfully",
1055 "type": "Application"
1056 },
1057 "400": {
1058 "description": "Bad Request - validation error"
1059 },
1060 "401": {
1061 "description": "Unauthorized"
1062 },
1063 "403": {
1064 "description": "Forbidden"
1065 },
1066 "404": {
1067 "description": "Not Found - organization does not exist"
1068 },
1069 "409": {
1070 "description": "Conflict - duplicate application name within organization"
1071 },
1072 "422": {
1073 "description": "Unprocessable Entity - validation error"
1074 },
1075 "500": {
1076 "description": "Internal Server Error"
1077 }
1078 }
1079 },
1080 {
1081 "id": "list_applications",
1082 "method": "GET",
1083 "path": "/v1/organizations/{organization_uuid}/applications",
1084 "scope": "applications:read",
1085 "aud": "organizations-api",
1086 "description": "Retrieve all applications for a specific organization. All query parameters are combined with AND logic.",
1087 "path_params": {
1088 "organization_uuid": {
1089 "type": "string",
1090 "format": "uuid",
1091 "required": true,
1092 "description": "Organization UUID"
1093 }
1094 },
1095 "query_params": {
1096 "name": {
1097 "type": "string",
1098 "optional": true,
1099 "description": "Filter by application name"
1100 },
1101 "class": {
1102 "type": "string",
1103 "enum": [
1104 "digital",
1105 "physical"
1106 ],
1107 "optional": true
1108 },
1109 "type": {
1110 "type": "string",
1111 "optional": true,
1112 "description": "Filter by application type"
1113 },
1114 "subtype": {
1115 "type": "string",
1116 "optional": true,
1117 "description": "Filter by application subtype"
1118 }
1119 },
1120 "responses": {
1121 "200": {
1122 "description": "Array of applications (empty if none found)",
1123 "type": "array",
1124 "items": "Application"
1125 },
1126 "403": {
1127 "description": "Forbidden"
1128 },
1129 "404": {
1130 "description": "Not Found - organization does not exist"
1131 },
1132 "500": {
1133 "description": "Internal Server Error"
1134 }
1135 }
1136 },
1137 {
1138 "id": "get_application",
1139 "method": "GET",
1140 "path": "/v1/applications/{applicationUuid}",
1141 "scope": "applications:read",
1142 "aud": "organizations-api",
1143 "description": "Retrieve a single application by UUID. User must have access to the application's organization.",
1144 "path_params": {
1145 "applicationUuid": {
1146 "type": "string",
1147 "format": "uuid",
1148 "required": true,
1149 "description": "Application UUID"
1150 }
1151 },
1152 "responses": {
1153 "200": {
1154 "description": "Application details",
1155 "type": "Application"
1156 },
1157 "401": {
1158 "description": "Unauthorized"
1159 },
1160 "404": {
1161 "description": "Not Found - application does not exist or user lacks access"
1162 },
1163 "500": {
1164 "description": "Internal Server Error"
1165 }
1166 }
1167 },
1168 {
1169 "id": "update_application",
1170 "method": "PATCH",
1171 "path": "/v1/applications/{applicationUuid}",
1172 "scope": "applications:write",
1173 "aud": "organizations-api",
1174 "description": "Partially update an application using PATCH semantics. Immutable fields: name, organizationUuid, claimantUuid, consumerUuid. User must have admin access to the organization.",
1175 "path_params": {
1176 "applicationUuid": {
1177 "type": "string",
1178 "format": "uuid",
1179 "required": true,
1180 "description": "Application UUID"
1181 }
1182 },
1183 "request_body": {
1184 "required": true,
1185 "content_type": "application/json",
1186 "all_fields_optional": true,
1187 "updatable_fields": [
1188 "status",
1189 "class",
1190 "type",
1191 "subtype",
1192 "channel",
1193 "operating_system",
1194 "deviceTypes",
1195 "userTypes"
1196 ],
1197 "non_updatable_fields": [
1198 "name",
1199 "organizationUuid",
1200 "claimantUuid",
1201 "consumerUuid"
1202 ]
1203 },
1204 "responses": {
1205 "200": {
1206 "description": "Updated application",
1207 "type": "Application"
1208 },
1209 "400": {
1210 "description": "Bad Request - validation error"
1211 },
1212 "401": {
1213 "description": "Unauthorized"
1214 },
1215 "404": {
1216 "description": "Not Found - application does not exist or user lacks access"
1217 },
1218 "500": {
1219 "description": "Internal Server Error"
1220 }
1221 }
1222 },
1223 {
1224 "id": "get_application_enums",
1225 "method": "GET",
1226 "path": "/v1/applications/enums",
1227 "scope": "applications:read",
1228 "aud": "organizations-api",
1229 "description": "Get valid enum values for application attributes. Some enum types require additional filter parameters based on hierarchical relationships.",
1230 "query_params": {
1231 "enum_name": {
1232 "type": "string",
1233 "required": true,
1234 "enum": ["status", "class", "type", "subtype", "architectureType", "operatingSystem", "deviceTypes"],
1235 "description": "The type of enum to retrieve"
1236 },
1237 "class": {
1238 "type": "string",
1239 "optional": true,
1240 "description": "Required when enum_name is: type, subtype, architectureType, operatingSystem, or deviceTypes"
1241 },
1242 "type": {
1243 "type": "string",
1244 "optional": true,
1245 "description": "Required when enum_name is: subtype"
1246 },
1247 "architecture_type": {
1248 "type": "string",
1249 "optional": true,
1250 "description": "Required when enum_name is: operatingSystem"
1251 }
1252 },
1253 "responses": {
1254 "200": {
1255 "description": "Array of enum values as strings",
1256 "type": "array",
1257 "items": "string",
1258 "example": ["personal", "business"]
1259 },
1260 "400": {
1261 "description": "Bad Request - missing enum_name or invalid enum_name value"
1262 },
1263 "401": {
1264 "description": "Unauthorized"
1265 },
1266 "500": {
1267 "description": "Internal Server Error"
1268 }
1269 },
1270 "enum_dependencies": {
1271 "description": "Comprehensive guide to enum dependencies and hierarchical relationships",
1272 "independent_enums": {
1273 "description": "These enums can be fetched without any parameters and return all available values",
1274 "enums": ["status", "class", "architectureType", "deviceTypes"]
1275 },
1276 "dependent_enums": {
1277 "type": {
1278 "depends_on": ["class"],
1279 "behavior": "FILTERING - Returns only types that are valid for the specified class value",
1280 "required_params": {
1281 "class": "Must be a valid class value (get from 'class' enum first)"
1282 },
1283 "example_call": "/v1/applications/enums?enum_name=type&class=digital",
1284 "error_if_missing": "400 Bad Request - Query parameter 'class' is required",
1285 "error_if_invalid": "422 Unprocessable Entity - Invalid class value"
1286 },
1287 "subtype": {
1288 "depends_on": ["class", "type"],
1289 "behavior": "FILTERING - Returns only subtypes that are valid for the specified class+type combination",
1290 "required_params": {
1291 "class": "Must be a valid class value",
1292 "type": "Must be a valid type value for the given class"
1293 },
1294 "example_call": "/v1/applications/enums?enum_name=subtype&class=digital&type=website",
1295 "error_if_missing": "400 Bad Request - Query parameters 'class' and 'type' are required",
1296 "error_if_invalid": "422 Unprocessable Entity - Invalid class or type value"
1297 },
1298 "operatingSystem": {
1299 "depends_on": ["architectureType"],
1300 "behavior": "VALIDATION ONLY - Validates that architecture_type exists but returns ALL operating systems (no filtering)",
1301 "required_params": {
1302 "architecture_type": "Must be a valid architectureType value (get from 'architectureType' enum first)"
1303 },
1304 "example_call": "/v1/applications/enums?enum_name=operatingSystem&architecture_type=native",
1305 "note": "Unlike type/subtype, this does NOT filter results by architecture_type. The parameter is required for validation only.",
1306 "error_if_missing": "400 Bad Request - Query parameter 'architectureType' is required",
1307 "error_if_invalid": "422 Unprocessable Entity - Invalid architectureType value"
1308 }
1309 },
1310 "recommended_fetch_order": {
1311 "description": "Order to fetch enums when building application creation forms",
1312 "steps": [
1313 "1. Fetch independent enums in parallel: status, class, architectureType, deviceTypes",
1314 "2. User selects 'class' value",
1315 "3. Fetch types filtered by selected class: GET /v1/applications/enums?enum_name=type&class={selected_class}",
1316 "4. User selects 'type' value",
1317 "5. Fetch subtypes filtered by selected class+type: GET /v1/applications/enums?enum_name=subtype&class={selected_class}&type={selected_type}",
1318 "6. If user selected architectureType, fetch operating systems: GET /v1/applications/enums?enum_name=operatingSystem&architecture_type={selected_architecture_type}"
1319 ]
1320 },
1321 "validation_mapping_table": {
1322 "description": "The API uses a database view 'application_class_type_to_subtype_readable' that defines valid combinations",
1323 "note": "Not all class+type+subtype combinations are valid. The /enums endpoint returns only valid combinations.",
1324 "validation_rule": "When creating/updating applications, if subtype is provided, the API validates that the class+type+subtype combination exists in the mapping table"
1325 }
1326 }
1327 },
1328 {
1329 "id": "get_domain",
1330 "method": "GET",
1331 "path": "/v1/domains/{domain}",
1332 "scope": "domains:read",
1333 "aud": "organizations-api",
1334 "description": "Retrieve domain details by domain name (read-only, does not trigger validation). Domain name is automatically normalized.",
1335 "path_params": {
1336 "domain": {
1337 "type": "string",
1338 "required": true,
1339 "description": "Domain name (will be normalized to lowercase, registerable domain extracted)"
1340 }
1341 },
1342 "responses": {
1343 "200": {
1344 "description": "Domain details with registration data",
1345 "type": "Domain"
1346 },
1347 "400": {
1348 "description": "Bad Request - invalid domain format"
1349 },
1350 "401": {
1351 "description": "Unauthorized"
1352 },
1353 "404": {
1354 "description": "Not Found - domain not in database"
1355 },
1356 "500": {
1357 "description": "Internal Server Error"
1358 }
1359 }
1360 },
1361 {
1362 "id": "create_domain",
1363 "method": "POST",
1364 "path": "/v1/domains",
1365 "scope": "domains:write",
1366 "aud": "organizations-api",
1367 "description": "Create and validate a domain using RDAP/WHOIS. This is the primary endpoint for creating domains. Domain is validated against external services before creation.",
1368 "request_body": {
1369 "required": true,
1370 "content_type": "application/json",
1371 "required_fields": [
1372 "domain"
1373 ],
1374 "example": {
1375 "domain": "example.com"
1376 }
1377 },
1378 "responses": {
1379 "200": {
1380 "description": "Domain validated and created successfully",
1381 "type": "Domain"
1382 },
1383 "400": {
1384 "description": "Bad Request - invalid domain format"
1385 },
1386 "401": {
1387 "description": "Unauthorized"
1388 },
1389 "404": {
1390 "description": "Not Found - domain not found via RDAP or WHOIS"
1391 },
1392 "500": {
1393 "description": "Internal Server Error"
1394 }
1395 }
1396 },
1397 {
1398 "id": "list_countries",
1399 "method": "GET",
1400 "path": "/v1/jurisdictions/countries",
1401 "scope": "organizations:read",
1402 "aud": "organizations-api",
1403 "description": "List all countries in the system with ISO codes",
1404 "responses": {
1405 "200": {
1406 "description": "Array of countries",
1407 "type": "array",
1408 "items": "Country"
1409 },
1410 "404": {
1411 "description": "Not Found"
1412 },
1413 "500": {
1414 "description": "Internal Server Error"
1415 }
1416 }
1417 },
1418 {
1419 "id": "list_subdivisions",
1420 "method": "GET",
1421 "path": "/v1/jurisdictions/subdivisions",
1422 "scope": "organizations:read",
1423 "aud": "organizations-api",
1424 "description": "Get subdivisions (states/provinces) of a country",
1425 "query_params": {
1426 "country": {
1427 "type": "string",
1428 "length": 2,
1429 "format": "iso2",
1430 "required": true,
1431 "example": "US",
1432 "description": "Country ISO2 code"
1433 }
1434 },
1435 "responses": {
1436 "200": {
1437 "description": "Array of subdivisions for the country",
1438 "type": "array",
1439 "items": "Subdivision"
1440 },
1441 "400": {
1442 "description": "Bad Request - country parameter invalid"
1443 },
1444 "404": {
1445 "description": "Not Found - country does not exist"
1446 },
1447 "500": {
1448 "description": "Internal Server Error"
1449 }
1450 }
1451 },
1452 {
1453 "id": "autocomplete_places",
1454 "method": "GET",
1455 "path": "/v1/jurisdictions/autocomplete",
1456 "scope": "organizations:read",
1457 "aud": "organizations-api",
1458 "description": "Autocomplete places using Google Places API v2. Returns up to 5 suggestions with structured address components.",
1459 "query_params": {
1460 "input": {
1461 "type": "string",
1462 "required": true,
1463 "min_length": 1,
1464 "max_length": 100,
1465 "example": "Boston",
1466 "description": "Search input for place autocomplete. Allowed characters: letters, numbers, spaces, hyphens, apostrophes, commas, periods, parentheses. Control characters rejected."
1467 },
1468 "type": {
1469 "type": "string",
1470 "enum": [
1471 "municipality",
1472 "district",
1473 "subdivision",
1474 "country"
1475 ],
1476 "optional": true,
1477 "description": "Filter results by place type"
1478 },
1479 "country": {
1480 "type": "string",
1481 "length": 2,
1482 "format": "iso2",
1483 "optional": true,
1484 "example": "US",
1485 "description": "Optional country filter (ISO2 code)"
1486 },
1487 "subdivision": {
1488 "type": "string",
1489 "optional": true,
1490 "case_insensitive": true,
1491 "example": "California",
1492 "description": "Optional subdivision filter (exact match, case-insensitive)"
1493 }
1494 },
1495 "responses": {
1496 "200": {
1497 "description": "Place suggestions with address components",
1498 "type": "PlacesAutocompleteResponse"
1499 },
1500 "400": {
1501 "description": "Bad Request - invalid input parameter"
1502 },
1503 "401": {
1504 "description": "Unauthorized"
1505 },
1506 "500": {
1507 "description": "Internal Server Error"
1508 }
1509 }
1510 },
1511 {
1512 "id": "list_sectors",
1513 "method": "GET",
1514 "path": "/v1/sectors",
1515 "scope": "organizations:read",
1516 "aud": "organizations-api",
1517 "description": "List all organization sectors",
1518 "responses": {
1519 "200": {
1520 "description": "Array of sectors",
1521 "type": "array",
1522 "items": "Sector"
1523 },
1524 "404": {
1525 "description": "Not Found"
1526 },
1527 "500": {
1528 "description": "Internal Server Error"
1529 }
1530 }
1531 },
1532 {
1533 "id": "list_structures_by_sector",
1534 "method": "GET",
1535 "path": "/v1/sectors/{id}/structures",
1536 "scope": "organizations:read",
1537 "aud": "organizations-api",
1538 "description": "Get organization structures for a specific sector",
1539 "path_params": {
1540 "id": {
1541 "type": "integer",
1542 "required": true,
1543 "description": "Sector ID"
1544 }
1545 },
1546 "responses": {
1547 "200": {
1548 "description": "Array of structures for the sector",
1549 "type": "array",
1550 "items": "Structure"
1551 },
1552 "404": {
1553 "description": "Not Found - sector does not exist"
1554 },
1555 "500": {
1556 "description": "Internal Server Error"
1557 }
1558 }
1559 }
1560 ],
1561 "enums": {
1562 "OrganizationSector": {
1563 "values": [
1564 "Public",
1565 "Private",
1566 "Non-profit"
1567 ],
1568 "case_sensitive": true,
1569 "description": "Economic sector classification"
1570 },
1571 "ClaimantType": {
1572 "values": [
1573 "USER",
1574 "ORGANIZATION"
1575 ],
1576 "case_sensitive": true,
1577 "description": "Type of entity claiming an organization"
1578 },
1579 "ValidationStatus": {
1580 "values": [
1581 "PENDING",
1582 "COMPLETED"
1583 ],
1584 "description": "Organization validation status by Attribute Validation Service"
1585 },
1586 "ApplicationStatus": {
1587 "values": [
1588 "active",
1589 "deprecated",
1590 "inactive",
1591 "closed"
1592 ],
1593 "description": "Application lifecycle status"
1594 },
1595 "ApplicationClass": {
1596 "values": [
1597 "digital",
1598 "physical"
1599 ],
1600 "description": "Application class - determines which conditional fields are allowed"
1601 },
1602 "ApplicationType": {
1603 "values": [
1604 "Self-Service",
1605 "Assisted Service",
1606 "Machine",
1607 "Internal Operations"
1608 ],
1609 "description": "Application type classification"
1610 },
1611 "Channel": {
1612 "values": [
1613 "spa",
1614 "web",
1615 "native",
1616 "service"
1617 ],
1618 "conditional": "Only valid when class='digital'",
1619 "description": "Application channel"
1620 },
1621 "OperatingSystem": {
1622 "values": [
1623 "ios",
1624 "android",
1625 "chromeos",
1626 "windows",
1627 "macos",
1628 "linux"
1629 ],
1630 "conditional": "Only valid when channel='native'",
1631 "description": "Operating system for native applications"
1632 },
1633 "DeviceType": {
1634 "values": [
1635 "mobile",
1636 "desktop"
1637 ],
1638 "conditional": "Only valid when class='digital'",
1639 "description": "Device types for digital applications"
1640 },
1641 "UserType": {
1642 "values": [
1643 "personal",
1644 "business"
1645 ],
1646 "description": "User types supported by application"
1647 },
1648 "PlaceType": {
1649 "values": [
1650 "municipality",
1651 "district",
1652 "subdivision",
1653 "country"
1654 ],
1655 "description": "Place type for autocomplete filtering"
1656 }
1657 },
1658 "code_generation_hints": {
1659 "validation_helpers": {
1660 "validate_match_keys": "if any([legalName, organizationSector, organizationStructure, jurisdictionOfFormation]): assert all([legalName, organizationSector, organizationStructure, jurisdictionOfFormation]) else raise 422",
1661 "validate_application_conditionals": "if channel: assert class=='digital'; if operating_system: assert channel=='native'; if deviceTypes: assert class=='digital'; assert len(userTypes)>0",
1662 "validate_address_fields": "if address provided: assert all([number, subdivisionIso2, countryIso2])",
1663 "normalize_domain": "domain_name = domain_name.lower().strip(); extract registerable domain using public suffix list"
1664 },
1665 "error_handling": {
1666 "401": {
1667 "action": "retry_with_token_refresh",
1668 "description": "Token expired or invalid - refresh OAuth2 token"
1669 },
1670 "403": {
1671 "action": "raise_forbidden_exception",
1672 "description": "User lacks required permissions"
1673 },
1674 "404": {
1675 "action": "raise_not_found_exception",
1676 "description": "Resource does not exist"
1677 },
1678 "409": {
1679 "action": "raise_conflict_exception",
1680 "description": "Duplicate resource (e.g., application name within org)"
1681 },
1682 "422": {
1683 "action": "raise_validation_exception_with_details",
1684 "description": "Validation error - incomplete match keys or invalid conditional fields"
1685 },
1686 "500": {
1687 "action": "retry_with_exponential_backoff",
1688 "description": "Internal server error - retry recommended"
1689 }
1690 },
1691 "client_structure": {
1692 "suggested_resources": [
1693 "OrganizationsResource",
1694 "ApplicationsResource",
1695 "DomainsResource",
1696 "JurisdictionsResource",
1697 "SectorsResource"
1698 ],
1699 "suggested_models": [
1700 "Organization",
1701 "Application",
1702 "Domain",
1703 "Address",
1704 "Country",
1705 "Subdivision",
1706 "Sector",
1707 "Structure",
1708 "PlacesAutocompleteResponse"
1709 ],
1710 "suggested_exceptions": [
1711 "APIException",
1712 "UnauthorizedException",
1713 "ForbiddenException",
1714 "NotFoundException",
1715 "ConflictException",
1716 "ValidationException",
1717 "UnprocessableEntityException"
1718 ]
1719 },
1720 "best_practices": {
1721 "token_management": "Store and reuse access tokens until expiration (300 seconds). Request new token when expired.",
1722 "error_retry": "Implement exponential backoff for 500 errors. Do not retry 4xx errors except 401.",
1723 "domain_normalization": "Always normalize domain names to lowercase before API calls to ensure consistency",
1724 "match_keys_validation": "Validate all match keys are present before making POST /v1/organizations to avoid 422 errors",
1725 "idempotency": "POST /v1/organizations is idempotent - safe to retry if uncertain whether organization was created",
1726 "pagination": "Use limit parameter for large result sets. Default limit is 100 for organization queries."
1727 }
1728 },
1729 "common_workflows": {
1730 "create_organization_workflow": {
1731 "steps": [
1732 "1. Get access token with organizations:write scope",
1733 "2. Optionally call GET /v1/sectors to get valid sector IDs",
1734 "3. Call GET /v1/sectors/{id}/structures to get valid structures for chosen sector",
1735 "4. Call GET /v1/jurisdictions/countries and /v1/jurisdictions/subdivisions to get valid jurisdiction codes",
1736 "5. Ensure all match keys are provided (legalName, organizationSector, organizationStructure, jurisdictionOfFormation)",
1737 "6. Call POST /v1/organizations with complete data",
1738 "7. API returns 201 with organization (or existing organization if match keys already exist)"
1739 ]
1740 },
1741 "create_application_workflow": {
1742 "steps": [
1743 "1. Get access token with applications:write scope",
1744 "2. Ensure organization exists (GET /v1/organizations/{uuid})",
1745 "3. Validate conditional fields based on class value",
1746 "4. Ensure userTypes array is not empty",
1747 "5. Call POST /v1/organizations/{organizationUuid}/applications",
1748 "6. API returns 201 with created application"
1749 ]
1750 },
1751 "create_and_validate_domain_workflow": {
1752 "steps": [
1753 "1. Get access token with domains:write scope",
1754 "2. Call POST /v1/domains with domain name",
1755 "3. API validates domain via RDAP/WHOIS and creates domain record",
1756 "4. Domain is now available for organization linking"
1757 ]
1758 },
1759 "search_organizations_by_domain_workflow": {
1760 "steps": [
1761 "1. Get access token with organizations:read scope",
1762 "2. Call GET /v1/organizations?domain=example.com",
1763 "3. API returns organization controlling the domain (only if relationship is validated)"
1764 ]
1765 }
1766 },
1767 "documentation_metadata": {
1768 "version": "1.0",
1769 "last_updated": "2026-02-18",
1770 "generated_by": "Claude Sonnet 4.5",
1771 "api_version": "2025-11-06.trust",
1772 "spec_format": "OpenAPI 3.0.4",
1773 "intended_audience": "AI agents (Claude, Cursor, etc.) for automated API client generation",
1774 "completeness_note": "This documentation includes all endpoints from the five main categories requested: /v1/organizations, /v1/applications, /v1/domains, /v1/sectors, and /v1/jurisdictions."
1775 }
1776}