From 29d096edcee00138b4fecb549b368b1fc87674d1 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Wed, 10 Sep 2025 02:05:23 -0400 Subject: [PATCH 1/4] RP-4333 identity control preview --- api-reference/preview/rp-4333.openapi.json | 1241 ++++++++++++++++++++ docs.json | 8 +- 2 files changed, 1248 insertions(+), 1 deletion(-) create mode 100644 api-reference/preview/rp-4333.openapi.json diff --git a/api-reference/preview/rp-4333.openapi.json b/api-reference/preview/rp-4333.openapi.json new file mode 100644 index 0000000..8435f0d --- /dev/null +++ b/api-reference/preview/rp-4333.openapi.json @@ -0,0 +1,1241 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Paxos Identity API", + "version": "identity control preview" + }, + "tags": [ + { + "name": "IdentityPublic" + } + ], + "paths": { + "/identity/identities/{id}": { + "get": { + "summary": "Get Identity", + "description": "Get an Identity by its (identity) id. You can only see identities created by you.\n\nYou can use the query parameter `include_details` to include identity details (`person_details` or `institution_details`) in\nthe response and the query parameter `include_institution_members` to include institution members in the response.", + "operationId": "GetIdentity", + "responses": { + "200": { + "description": "A successful response.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Identity" + } + } + } + } + }, + "parameters": [ + { + "name": "id", + "description": "id associated with the identity", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "include_details", + "description": "query param; details are encrypted, so we do not want to include them by default", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "include_institution_members", + "description": "query param; to include institution members for institution identity", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "tags": [ + "Identity" + ], + "security": [ + { + "OAuth2": [ + "identity:read_identity" + ] + } + ] + } + }, + "/v2/identity/identities/{identity_id}/controls": { + "get": { + "summary": "Get Identity Controls", + "description": "Get the current control settings for an identity.", + "operationId": "GetIdentityControls", + "responses": { + "200": { + "description": "A successful response.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityControls" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "name": "identity_id", + "description": "The Identity ID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "tags": ["Identity Controls"], + "security": [ + { + "OAuth2": ["identity:read_identity"] + } + ] + }, + "put": { + "summary": "Update Identity Controls", + "description": "Update control settings for an identity including frozen, dormant, and closed states.", + "operationId": "UpdateIdentityControls", + "responses": { + "200": { + "description": "A successful response.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityControls" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "name": "identity_id", + "description": "The Identity ID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateIdentityControlsRequest" + } + } + }, + "required": true + }, + "tags": ["Identity Controls"], + "security": [ + { + "OAuth2": ["identity:write_identity"] + } + ] + } + } + }, + "components": { + "schemas": { + "CustomerDueDiligenceNetWorthRange": { + "type": "string", + "enum": [ + "NET_WORTH_0_TO_100K", + "NET_WORTH_100K_TO_500K", + "NET_WORTH_500K_TO_1M", + "NET_WORTH_1M_TO_2_5M", + "NET_WORTH_2_5M_TO_5M", + "NET_WORTH_5M_TO_7_5M", + "NET_WORTH_7_5M_TO_10M", + "NET_WORTH_10M_TO_25M", + "NET_WORTH_25M_TO_50M", + "NET_WORTH_OVER_50M" + ] + }, + "CustomerDueDiligenceTransferValueRange": { + "type": "string", + "enum": [ + "TRANSFER_VALUE_0_TO_25K", + "TRANSFER_VALUE_25K_TO_50K", + "TRANSFER_VALUE_50K_TO_100K", + "TRANSFER_VALUE_100K_TO_250K", + "TRANSFER_VALUE_250K_TO_500K", + "TRANSFER_VALUE_500K_TO_750K", + "TRANSFER_VALUE_750K_TO_1M", + "TRANSFER_VALUE_1M_TO_2_5M", + "TRANSFER_VALUE_2_5M_TO_5M", + "TRANSFER_VALUE_ABOVE_5M" + ] + }, + "CustomerDueDiligenceYearlyIncomeRange": { + "type": "string", + "enum": [ + "INCOME_0_TO_50K", + "INCOME_50K_TO_100K", + "INCOME_100K_TO_250K", + "INCOME_250K_TO_500K", + "INCOME_500K_TO_750K", + "INCOME_750K_TO_1M", + "INCOME_ABOVE_1M" + ] + }, + "MerchantFundingSourceFundingSource": { + "type": "string", + "enum": [ + "BUSINESS_LOANS_FINANCING", + "SALARY_SAVINGS", + "INVESTMENT_GAINS", + "INHERITANCE", + "REAL_ESTATE_INCOME", + "NON_PROFIT_SOURCES", + "OTHER_BUSINESS_INCOME" + ] + }, + "PassthroughVerificationField": { + "type": "string", + "enum": [ + "FULL_LEGAL_NAME", + "ADDRESS", + "DATE_OF_BIRTH", + "CIP_ID" + ] + }, + "PersonDetailsCIPIDType": { + "type": "string", + "enum": [ + "SSN", + "ID_CARD", + "ITIN", + "PASSPORT", + "DRIVING_LICENSE", + "VISA" + ], + "title": "" + }, + "identityprotoVerifierType": { + "type": "string", + "enum": [ + "JUMIO", + "PAXOS", + "PASSTHROUGH", + "MANUAL" + ] + }, + "AccountPurpose": { + "type": "string", + "enum": [ + "INVESTMENT_TRADING", + "SAVINGS", + "STABLECOIN_PURCHASE_REDEMPTION" + ] + }, + "CustomerDueDiligence": { + "type": "object", + "properties": { + "aliases": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of alternate names or aliases associated with the Identity." + }, + "estimated_net_worth": { + "$ref": "#/components/schemas/CustomerDueDiligenceNetWorthRange" + }, + "estimated_yearly_income": { + "$ref": "#/components/schemas/CustomerDueDiligenceYearlyIncomeRange" + }, + "expected_transfer_value": { + "$ref": "#/components/schemas/CustomerDueDiligenceTransferValueRange" + }, + "source_of_wealth": { + "$ref": "#/components/schemas/WealthSource" + }, + "source_of_funds": { + "$ref": "#/components/schemas/FundsSource" + }, + "purpose_of_account": { + "$ref": "#/components/schemas/AccountPurpose" + }, + "employment_status": { + "$ref": "#/components/schemas/EmploymentStatus" + }, + "employment_industry_sector": { + "$ref": "#/components/schemas/InstitutionSubType" + }, + "industry_sector": { + "$ref": "#/components/schemas/InstitutionSubType" + }, + "has_underlying_trust_structure": { + "type": "boolean", + "description": "Whether or not the institution tied to the Identity has an underlying trust structure." + }, + "has_nominee_shareholders": { + "type": "boolean", + "description": "Whether or not the institution tied to the Identity has nominee shareholders." + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "When the customer due diligence was created" + }, + "is_publicly_traded": { + "type": "boolean", + "description": "`true` or `false` indicating whether or not the company is listed on a public stock exchange." + }, + "merchant_funding_source": { + "$ref": "#/components/schemas/MerchantFundingSourceFundingSource" + }, + "customer_regions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CustomerRegion" + }, + "description": "Regions where the customer base is located." + } + } + }, + "CustomerRegion": { + "type": "string", + "enum": [ + "US_CANADA", + "MEXICO_CENTRAL_AMERICA", + "SOUTH_AMERICA", + "EUROPE", + "ASIA", + "AFRICA", + "OCEANIA" + ] + }, + "EmploymentStatus": { + "type": "string", + "enum": [ + "CONTRACTUAL", + "FULL_TIME", + "PART_TIME", + "RETIRED", + "SELF_EMPLOYED", + "STUDENT", + "UNEMPLOYED" + ] + }, + "FundsSource": { + "type": "string", + "enum": [ + "SALARY_DISBURSEMENT", + "INHERITANCE_DISTRIBUTION", + "INVESTMENT_RETURNS", + "BUSINESS_DIVIDENDS_PROFITS", + "PROPERTY_SALE", + "LOAN_DISBURSEMENT", + "SAVINGS_ACCOUNT_WITHDRAWAL", + "GOVERNMENT_BENEFITS" + ] + }, + "Identity": { + "type": "object", + "example": { + "id": "f190b163-208f-4d73-8deb-4fb8b24add00", + "status": "DISABLED", + "status_details": { + "active_controls": [ + { + "control": "CLIENT_DISABLED", + "reason": "some client-set reason" + }, + { + "control": "ADMIN_DISABLED", + "reason": "some admin-set reason" + }, + { + "control": "ADMIN_FROZEN", + "reason": "some admin-set reason" + }, + { + "control": "DORMANT", + "reason": "some reason" + } + ], + "pending_requirements": [ + { + "requirement": "PENDING_ID_VERIFICATION", + "message": "ID Verification" + }, + { + "requirement": "PENDING_SANCTIONS_SCREENING", + "message": "Sanctions Screening" + }, + { + "requirement": "PENDING_ADDITIONAL_SCREENING", + "message": "PEP/Adverse Media Screening" + }, + { + "requirement": "PENDING_MEMBERS", + "message": "Pending members", + "metadata": { + "f190b163-208f-4d73-8deb-000000000001": "PENDING" + } + } + ], + "failed_requirements": [ + { + "requirement": "FAILED_ENHANCED_DUE_DILIGENCE", + "message": "Enhanced Due Diligence" + }, + { + "requirement": "FAILED_RISK_AWARENESS_ASSESSMENT", + "message": "Risk Awareness Assessment" + }, + { + "requirement": "DISABLED_MEMBERS", + "message": "Disabled members", + "metadata": { + "f190b163-208f-4d73-8deb-000000000002": "DISABLED" + } + }, + { + "requirement": "RISK_RATING", + "message": "Jurisdiction not supported by Paxos" + } + ] + } + }, + "properties": { + "id": { + "type": "string", + "title": "The id used for all other interactions with this account" + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "API User-facing metadata" + }, + "summary_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "user_disabled": { + "type": "boolean", + "title": "true if the account has been disabled by the API user" + }, + "admin_disabled": { + "type": "boolean", + "title": "true if the account has been disabled by a Paxos admin" + }, + "person_details": { + "$ref": "#/components/schemas/PersonDetails" + }, + "type": { + "$ref": "#/components/schemas/IdentityType" + }, + "ref_id": { + "type": "string", + "description": "A user-facing ID to prevent duplicate account creation. Unique for all accounts created by the same API user." + }, + "institution_details": { + "$ref": "#/components/schemas/InstitutionDetails" + }, + "institution_members": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InstitutionMember" + }, + "title": "members associated with institution identity type" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The time at which the identity is created at. RFC3339 format, like `YYYY-MM-DDTHH:MM:SS.sssZ`. ex: `2006-01-02T15:04:05Z`." + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "The time at which the identity is updated at. RFC3339 format, like `YYYY-MM-DDTHH:MM:SS.sssZ`. ex: `2006-01-02T15:04:05Z`." + }, + "tax_details": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TaxDetail" + }, + "title": "tax payer details" + }, + "tax_details_not_required": { + "type": "boolean", + "title": "whether or not tax_details are legally required" + }, + "summary_tin_verification_status": { + "$ref": "#/components/schemas/TINVerificationStatus" + }, + "customer_due_diligence": { + "$ref": "#/components/schemas/CustomerDueDiligence" + }, + "is_merchant": { + "type": "boolean", + "description": "True if the identity is a merchant." + }, + "last_kyc_refresh_date": { + "type": "string", + "format": "date-time", + "description": "The last timestamp the identity has undergone a periodic kyc refresh. RFC3339 format, like `YYYY-MM-DDTHH:MM:SS.sssZ`. ex: `2006-01-02T15:04:05Z`." + }, + "status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "status_details": { + "$ref": "#/components/schemas/IdentityStatusDetails" + } + }, + "required": [ + "id" + ] + }, + "IdentityMailingAddress": { + "type": "object", + "properties": { + "country": { + "type": "string", + "maxLength": 35, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "address1": { + "type": "string", + "maxLength": 35, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "address2": { + "type": "string", + "description": "To clear address2 (i.e. when updating an identity), set address2 to an empty string (\"\").", + "maxLength": 35, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "city": { + "type": "string", + "maxLength": 35, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "province": { + "type": "string", + "maxLength": 35, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "zip_code": { + "type": "string", + "maxLength": 35, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + } + }, + "description": "A mailing address.", + "required": [ + "country", + "address1", + "city", + "province" + ] + }, + "IdentityStatus": { + "type": "string", + "enum": [ + "PENDING", + "ERROR", + "APPROVED", + "DENIED", + "DISABLED" + ], + "title": "" + }, + "IdentityType": { + "type": "string", + "enum": [ + "PERSON", + "INSTITUTION" + ] + }, + "InstitutionCIPIDType": { + "type": "string", + "enum": [ + "EIN", + "SSN", + "ITIN", + "REGISTRATION_NUMBER" + ], + "title": "" + }, + "InstitutionDetails": { + "type": "object", + "properties": { + "sanctions_verification_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "name": { + "type": "string", + "title": "Allowed in create and update", + "maxLength": 200, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "business_address": { + "$ref": "#/components/schemas/IdentityMailingAddress" + }, + "phone_number": { + "type": "string", + "title": "Allowed in create and update" + }, + "email": { + "type": "string", + "title": "Allowed in create and update" + }, + "institution_type": { + "$ref": "#/components/schemas/InstitutionType" + }, + "institution_sub_type": { + "$ref": "#/components/schemas/InstitutionSubType" + }, + "cip_id": { + "type": "string", + "title": "Allowed in create and update\nSSN format: xxx-xx-xxxx\nITIN format: xxx-xx-xxxx\nEIN format: xx-xxxxxxx", + "maxLength": 200, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "cip_id_type": { + "$ref": "#/components/schemas/InstitutionCIPIDType" + }, + "cip_id_country": { + "type": "string", + "description": "Allowed in create and update. Must be an ISO 3166-1 alpha 3 code." + }, + "govt_registration_date": { + "type": "string", + "format": "date-time", + "title": "date at which the institution is registered with govt" + }, + "incorporation_address": { + "$ref": "#/components/schemas/IdentityMailingAddress" + }, + "regulation_status": { + "$ref": "#/components/schemas/RegulationStatus" + }, + "trading_type": { + "$ref": "#/components/schemas/TradingType" + }, + "listed_exchange": { + "type": "string", + "title": "exchange in which the institution is listed" + }, + "ticker_symbol": { + "type": "string", + "description": "Ticker symbol of the institution if publicly traded or ticker symbol of the parent institution." + }, + "parent_institution_name": { + "type": "string", + "title": "name of the parent institution if the institution is a subsidiary of parent institution" + }, + "regulator_name": { + "type": "string", + "title": "name of the financial regulator" + }, + "regulator_jurisdiction": { + "type": "string", + "title": "country or jurisdiction of financial regulator" + }, + "regulator_register_number": { + "type": "string", + "title": "registrar number of regulator" + }, + "document_verification_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "additional_screening_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "doing_business_as": { + "type": "string", + "title": "Allowed in create and update" + }, + "business_description": { + "type": "string", + "title": "free text description of business" + } + } + }, + "InstitutionMember": { + "type": "object", + "properties": { + "identity_id": { + "type": "string", + "title": "The ID of the member identity" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InstitutionRoleType" + }, + "title": "The type of membership this identity has in the institution" + }, + "ownership": { + "type": "string", + "description": "Decimal number representing the percent ownership the identity has in the company-- e.g. 5 represents 5% ownership." + }, + "position": { + "type": "string", + "title": "The position the identity holds with the company" + }, + "name": { + "type": "string", + "title": "Member's full name. Not writable from API" + }, + "summary_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "id": { + "type": "string", + "description": "Institution member ID. Note: This field is auto-generated. Specifying an ID when creating an institution member is a client error." + } + } + }, + "InstitutionRoleType": { + "type": "string", + "enum": [ + "BENEFICIAL_OWNER", + "ACCOUNT_OPENER", + "TRUSTEE", + "AUTHORIZED_USER", + "GRANTOR", + "MANAGEMENT_CONTROL_PERSON", + "BENEFICIARY" + ], + "title": "" + }, + "InstitutionSubType": { + "type": "string", + "enum": [ + "INVESTMENT", + "HEDGE_FUND", + "MONEY_SERVICE_BUSINESS", + "STO_ISSUER", + "PRECIOUS_METALS", + "NON_PROFIT", + "REGISTERED_INVESTMENT_ADVISOR", + "AGRICULTURE_FORESTRY_FISHING_HUNTING", + "MINING", + "UTILITIES", + "CONSTRUCTION", + "MANUFACTURING", + "WHOLESALE_TRADE", + "RETAIL_TRADE", + "TRANSPORTATION_WAREHOUSING", + "INFORMATION", + "FINANCE_INSURANCE", + "REAL_ESTATE_RENTAL_LEASING", + "PROFESSIONAL_SCIENTIFIC_TECHNICAL_SERVICES", + "MANAGEMENT_OF_COMPANIES_ENTERPRISES", + "ADMINISTRATIVE_SUPPORT_WASTE_MANAGEMENT_REMEDIATION_SERVICES", + "EDUCATIONAL_SERVICES", + "HEALTH_CARE_SOCIAL_ASSISTANCE", + "ARTS_ENTERTAINMENT_RECREATION", + "ACCOMMODATION_FOOD_SERVICES", + "OTHER_SERVICES", + "PUBLIC_ADMINISTRATION", + "NOT_CLASSIFIED", + "ADULT_ENTERTAINMENT", + "AUCTIONS", + "AUTOMOBILES", + "BLOCKCHAIN", + "CRYPTO", + "DRUGS", + "EXPORT_IMPORT", + "E_COMMERCE", + "FINANCIAL_INSTITUTION", + "GAMBLING", + "INSURANCE", + "MARKET_MAKER", + "SHELL_BANK", + "TRAVEL_TRANSPORT", + "WEAPONS" + ], + "title": "" + }, + "InstitutionType": { + "type": "string", + "enum": [ + "TRUST", + "CORPORATION", + "LLC", + "PARTNERSHIP" + ], + "title": "" + }, + "PassthroughVerifierType": { + "type": "string", + "enum": [ + "JUMIO", + "ALLOY", + "LEXISNEXIS", + "MITEK", + "SUMSUB", + "MICROBILT", + "ONFIDO", + "CUSTOMER", + "EQUIFAX", + "ID3_AUTHENTICATE", + "FIS", + "PROVE", + "PERSONA", + "PLAID" + ] + }, + "PersonDetails": { + "type": "object", + "properties": { + "id_verification_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "sanctions_verification_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "first_name": { + "type": "string", + "title": "Allowed in create and update", + "maxLength": 200, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "last_name": { + "type": "string", + "title": "Allowed in create and update", + "maxLength": 200, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "date_of_birth": { + "type": "string", + "title": "Allowed in create and update", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" + }, + "govt_id": { + "type": "string", + "title": "DEPRECATED: use cip_id instead", + "maxLength": 200, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "address": { + "$ref": "#/components/schemas/IdentityMailingAddress" + }, + "phone_number": { + "type": "string", + "title": "Allowed in create and update" + }, + "email": { + "type": "string", + "title": "Allowed in create and update" + }, + "nationality": { + "type": "string", + "description": "Allowed in create and update. Must be an ISO 3166-1 alpha 3 code.", + "pattern": "^[A-Z]{3}$" + }, + "verifier_id": { + "type": "string", + "title": "Allowed in create and update. The id used by the external verifier. For Jumio, this is the \"transaction reference\"" + }, + "verifier_type": { + "$ref": "#/components/schemas/identityprotoVerifierType" + }, + "id_verification_url": { + "type": "string", + "title": "When PAXOS verifier is used, the iframe url returned for ID verification" + }, + "passthrough_verifier_type": { + "$ref": "#/components/schemas/PassthroughVerifierType" + }, + "passthrough_verified_at": { + "type": "string", + "format": "date-time", + "title": "When PASSTHROUGH verifier is used, this specifies the time that ID verification was completed" + }, + "govt_id_type": { + "$ref": "#/components/schemas/PersonDetailsCIPIDType" + }, + "cip_id": { + "type": "string", + "title": "SSN or TIN, unique for each Identity object. Allowed in create and update\nSSN format: xxx-xx-xxxx\nITIN format: xxx-xx-xxxx\nEIN format: xx-xxxxxxx", + "maxLength": 200, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "cip_id_type": { + "$ref": "#/components/schemas/PersonDetailsCIPIDType" + }, + "cip_id_country": { + "type": "string", + "description": "Allowed in create and update. Must be an ISO 3166-1 alpha 3 code." + }, + "additional_screening_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "profession": { + "type": "string", + "description": "Allowed in create and update." + }, + "middle_name": { + "type": "string", + "title": "Allowed in create and update", + "maxLength": 200 + }, + "country_of_birth": { + "type": "string", + "description": "Allowed in create and update." + }, + "passthrough_verification_id": { + "type": "string", + "description": "Unique identifier for the underlying person's ID verification record." + }, + "passthrough_verification_status": { + "$ref": "#/components/schemas/IdentityStatus" + }, + "passthrough_verification_fields": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PassthroughVerificationField" + }, + "description": "List of verification fields used by the external verifier to validate the person's identity." + } + } + }, + "RegulationStatus": { + "type": "string", + "enum": [ + "US_REGULATED", + "INTL_REGULATED", + "NON_REGULATED" + ] + }, + "TINVerificationStatus": { + "type": "string", + "enum": [ + "TIN_VERIFICATION_PENDING", + "TIN_VERIFICATION_ERROR", + "TIN_VERIFICATION_VALID" + ], + "description": "The TIN verification status for the associated `tax_payer_id`." + }, + "TaxDetail": { + "type": "object", + "properties": { + "tax_payer_id": { + "type": "string", + "title": "For U.S. citizens it is the SSN, TIN or EIN. For Brazil citizens, it is the CPF. Allowed in create and update", + "maxLength": 35, + "pattern": "^[0-9A-Za-z /?:().,&'+-]+$" + }, + "tax_payer_country": { + "type": "string", + "title": "Allowed in create and update. Must be an ISO 3166-1 alpha 3 code" + }, + "tin_verification_status": { + "$ref": "#/components/schemas/TINVerificationStatus" + } + } + }, + "TradingType": { + "type": "string", + "enum": [ + "PRIVATE", + "PUBLIC", + "PUBLICLY_TRADED_SUBSIDIARY" + ] + }, + "WealthSource": { + "type": "string", + "enum": [ + "INHERITANCE", + "INVESTMENT_GAINS", + "BUSINESS_OWNERSHIP_DIVIDENDS", + "EMPLOYMENT_INCOME", + "REAL_ESTATE", + "OTHER_SOURCE_OF_WEALTH" + ] + }, + "IdentityControlType": { + "type": "string", + "enum": [ + "CLIENT_DISABLED", + "ADMIN_DISABLED", + "ADMIN_FROZEN", + "DORMANT" + ] + }, + "ClientIdentityControlType": { + "type": "string", + "enum": [ + "CLIENT_DISABLED", + "DORMANT" + ] + }, + "IdentityControlAction": { + "type": "string", + "enum": [ + "SET", + "CLEAR" + ] + }, + "IdentityControl": { + "type": "object", + "properties": { + "control": { + "$ref": "#/components/schemas/IdentityControlType" + }, + "reason": { + "type": "string", + "description": "Reason why this identity control was set" + } + } + }, + "IdentityControls": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IdentityControl" + } + }, + "UpdateIdentityControlsRequest": { + "type": "object", + "properties": { + "control": { + "$ref": "#/components/schemas/ClientIdentityControlType" + }, + "action": { + "$ref": "#/components/schemas/IdentityControlAction" + }, + "reason": { + "type": "string", + "description": "Freetext reason for setting or clearing the control" + } + }, + "required": ["control", "action"] + }, + "IdentityPendingRequirementType": { + "type": "string", + "enum": [ + "PENDING_ID_VERIFICATION", + "PENDING_SANCTIONS_SCREENING", + "PENDING_ADDITIONAL_SCREENING", + "PENDING_ENHANCED_DUE_DILIGENCE", + "PENDING_RISK_AWARENESS_ASSESSMENT", + "PENDING_MEMBERS" + ] + }, + "IdentityFailedRequirementType": { + "type": "string", + "enum": [ + "FAILED_ID_VERIFICATION", + "FAILED_SANCTIONS_SCREENING", + "FAILED_ADDITIONAL_SCREENING", + "FAILED_ENHANCED_DUE_DILIGENCE", + "FAILED_RISK_AWARENESS_ASSESSMENT", + "DISABLED_MEMBERS", + "EXPIRED_KYC_REFRESH", + "RISK_RATING" + ] + }, + "IdentityPendingRequirement": { + "type": "object", + "properties": { + "requirement": { + "$ref": "#/components/schemas/IdentityPendingRequirementType" + }, + "message": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "IdentityFailedRequirement": { + "type": "object", + "properties": { + "requirement": { + "$ref": "#/components/schemas/IdentityFailedRequirementType" + }, + "message": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "IdentityStatusDetails": { + "type": "object", + "properties": { + "active_controls": { + "$ref": "#/components/schemas/IdentityControls" + }, + "pending_requirements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IdentityPendingRequirement" + } + }, + "failed_requirements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IdentityFailedRequirement" + } + } + } + } + }, + "responses": { + "BadRequest": { + "description": "Bad Request", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/examples/Problem_bad_request" + } + } + } + }, + "Unauthorized": { + "description": "Unauthorized", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/examples/Problem_unauthorized" + } + } + } + }, + "Forbidden": { + "description": "Forbidden", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/examples/Problem_forbidden" + } + } + } + }, + "NotFound": { + "description": "Not Found", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/examples/Problem_not_found" + } + } + } + }, + "TooManyRequests": { + "description": "Too Many Requests", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/examples/Problem_too_many_requests" + } + } + } + }, + "InternalServerError": { + "description": "Internal Server Error", + "content": { + "application/problem+json": { + "schema": { + "$ref": "#/components/examples/Problem_internal_server_error" + } + } + } + } + }, + "examples": { + "Problem_bad_request": { + "value": { + "type": "about:blank", + "title": "Bad Request", + "status": 400, + "detail": "Invalid request format or missing required fields" + } + }, + "Problem_unauthorized": { + "value": { + "type": "about:blank", + "title": "Unauthorized", + "status": 401, + "detail": "no authorization header set" + } + }, + "Problem_forbidden": { + "value": { + "type": "about:blank", + "title": "Forbidden", + "status": 403, + "detail": "user account is disabled" + } + }, + "Problem_not_found": { + "value": { + "type": "about:blank", + "title": "Not Found", + "status": 404, + "detail": "identity not found" + } + }, + "Problem_too_many_requests": { + "value": { + "type": "about:blank", + "title": "Too Many Requests", + "status": 429, + "detail": "Too many requests" + } + }, + "Problem_internal_server_error": { + "value": { + "type": "about:blank", + "title": "Internal Server Error", + "status": 500 + } + } + } + } +} diff --git a/docs.json b/docs.json index 808d619..834e4e6 100644 --- a/docs.json +++ b/docs.json @@ -834,7 +834,6 @@ }, { "tab": "Previews", - "hidden": true, "groups": [ { "group": "Previews", @@ -848,6 +847,13 @@ "source": "api-reference/preview/paxos-v2-preview-orchestration.openapi.json", "directory": "api-reference/preview" } + }, + { + "group": "RP-4333 Identity Previews", + "openapi": { + "source": "api-reference/preview/rp-4333.openapi.json", + "directory": "api-reference/preview" + } } ] }, From 3a7a50e6b3050ed5942e241bf521088383978549 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Wed, 10 Sep 2025 02:08:32 -0400 Subject: [PATCH 2/4] preview --- docs.json | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/docs.json b/docs.json index 834e4e6..b977026 100644 --- a/docs.json +++ b/docs.json @@ -835,19 +835,6 @@ { "tab": "Previews", "groups": [ - { - "group": "Previews", - "pages": [ - "api-reference/preview/overview" - ] - }, - { - "group": "Orchestration Previews", - "openapi": { - "source": "api-reference/preview/paxos-v2-preview-orchestration.openapi.json", - "directory": "api-reference/preview" - } - }, { "group": "RP-4333 Identity Previews", "openapi": { From 5f6b2e20d4453d4a360282142bcab07c4bba714d Mon Sep 17 00:00:00 2001 From: Lawrence Date: Wed, 10 Sep 2025 02:16:14 -0400 Subject: [PATCH 3/4] example --- api-reference/preview/rp-4333.openapi.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/api-reference/preview/rp-4333.openapi.json b/api-reference/preview/rp-4333.openapi.json index 8435f0d..ebb2631 100644 --- a/api-reference/preview/rp-4333.openapi.json +++ b/api-reference/preview/rp-4333.openapi.json @@ -1029,7 +1029,25 @@ "type": "array", "items": { "$ref": "#/components/schemas/IdentityControl" - } + }, + "example": [ + { + "control": "CLIENT_DISABLED", + "reason": "some client-set reason" + }, + { + "control": "ADMIN_DISABLED", + "reason": "some admin-set reason" + }, + { + "control": "ADMIN_FROZEN", + "reason": "some admin-set reason" + }, + { + "control": "DORMANT", + "reason": "some reason" + } + ] }, "UpdateIdentityControlsRequest": { "type": "object", From f4c95320573b800e0ce79f3bf97e14ed105f9dd2 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 10 Sep 2025 15:19:03 +0100 Subject: [PATCH 4/4] Refactor identity control API documentation: updated endpoint summaries, added new POST and DELETE operations for identity controls, and revised request/response schemas to enhance clarity and functionality. --- api-reference/preview/rp-4333.openapi.json | 170 ++++++++++++++++----- 1 file changed, 130 insertions(+), 40 deletions(-) diff --git a/api-reference/preview/rp-4333.openapi.json b/api-reference/preview/rp-4333.openapi.json index ebb2631..bb59fd7 100644 --- a/api-reference/preview/rp-4333.openapi.json +++ b/api-reference/preview/rp-4333.openapi.json @@ -70,9 +70,9 @@ }, "/v2/identity/identities/{identity_id}/controls": { "get": { - "summary": "Get Identity Controls", - "description": "Get the current control settings for an identity.", - "operationId": "GetIdentityControls", + "summary": "List Identity Controls", + "description": "List the current control settings for an identity.", + "operationId": "ListIdentityControls", "responses": { "200": { "description": "A successful response.", @@ -115,10 +115,72 @@ } ] }, - "put": { - "summary": "Update Identity Controls", - "description": "Update control settings for an identity including frozen, dormant, and closed states.", - "operationId": "UpdateIdentityControls", + "post": { + "summary": "Create Identity Control", + "description": "Create a new control setting for an identity.", + "operationId": "CreateIdentityControl", + "responses": { + "200": { + "description": "A successful response.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IdentityControl" + }, + "example": { + "control": "FROZEN", + "set_by": "client", + "reason_code": "CUSTOMER_REQUESTED", + "reason": "Customer requested temporary account freeze" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "parameters": [ + { + "name": "identity_id", + "description": "The Identity ID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateIdentityControlRequest" + } + } + }, + "required": true + }, + "tags": ["Identity Controls"], + "security": [ + { + "OAuth2": ["identity:write_identity"] + } + ] + }, + "delete": { + "summary": "Delete Identity Control", + "description": "Delete/unset a specific control on an identity.", + "operationId": "DeleteIdentityControl", "responses": { "200": { "description": "A successful response.", @@ -158,7 +220,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateIdentityControlsRequest" + "$ref": "#/components/schemas/DeleteIdentityControlRequest" } } }, @@ -378,20 +440,22 @@ "status_details": { "active_controls": [ { - "control": "CLIENT_DISABLED", - "reason": "some client-set reason" - }, - { - "control": "ADMIN_DISABLED", - "reason": "some admin-set reason" + "control": "FROZEN", + "set_by": "client", + "reason_code": "CUSTOMER_REQUESTED", + "reason": "Pending customer verification" }, { - "control": "ADMIN_FROZEN", - "reason": "some admin-set reason" + "control": "FROZEN", + "set_by": "paxos", + "reason_code": "SANCTIONS_PEP_OR_NN", + "reason": "Potential PEP match requires review" }, { - "control": "DORMANT", - "reason": "some reason" + "control": "CLOSED", + "set_by": "client", + "reason_code": "DORMANT", + "reason": "Account inactive for extended period" } ], "pending_requirements": [ @@ -993,19 +1057,26 @@ "IdentityControlType": { "type": "string", "enum": [ - "CLIENT_DISABLED", - "ADMIN_DISABLED", - "ADMIN_FROZEN", - "DORMANT" + "FROZEN", + "CLOSED" ] }, "ClientIdentityControlType": { "type": "string", "enum": [ - "CLIENT_DISABLED", - "DORMANT" + "FROZEN", + "CLOSED" ] }, + "IdentityControlReasonCode": { + "type": "string", + "enum": [ + "DORMANT", + "CUSTOMER_REQUESTED", + "SANCTIONS_PEP_OR_NN" + ], + "description": "Standardized reason codes for identity control actions" + }, "IdentityControlAction": { "type": "string", "enum": [ @@ -1019,9 +1090,17 @@ "control": { "$ref": "#/components/schemas/IdentityControlType" }, + "set_by": { + "type": "string", + "enum": ["paxos", "client"], + "description": "Who set this control - either 'paxos' or 'client'" + }, + "reason_code": { + "$ref": "#/components/schemas/IdentityControlReasonCode" + }, "reason": { "type": "string", - "description": "Reason why this identity control was set" + "description": "Additional details about why this identity control was set" } } }, @@ -1032,38 +1111,49 @@ }, "example": [ { - "control": "CLIENT_DISABLED", - "reason": "some client-set reason" + "control": "FROZEN", + "set_by": "client", + "reason_code": "CUSTOMER_REQUESTED", + "reason": "Customer requested temporary account freeze" }, { - "control": "ADMIN_DISABLED", - "reason": "some admin-set reason" + "control": "FROZEN", + "set_by": "paxos", + "reason_code": "SANCTIONS_PEP_OR_NN", + "reason": "Account flagged for sanctions screening" }, { - "control": "ADMIN_FROZEN", - "reason": "some admin-set reason" - }, - { - "control": "DORMANT", - "reason": "some reason" + "control": "CLOSED", + "set_by": "client", + "reason_code": "DORMANT", + "reason": "No activity for 12 months" } ] }, - "UpdateIdentityControlsRequest": { + "CreateIdentityControlRequest": { "type": "object", "properties": { "control": { "$ref": "#/components/schemas/ClientIdentityControlType" }, - "action": { - "$ref": "#/components/schemas/IdentityControlAction" + "reason_code": { + "$ref": "#/components/schemas/IdentityControlReasonCode" }, "reason": { "type": "string", - "description": "Freetext reason for setting or clearing the control" + "description": "Additional free text details about the reason for setting the control" + } + }, + "required": ["control", "reason_code"] + }, + "DeleteIdentityControlRequest": { + "type": "object", + "properties": { + "control": { + "$ref": "#/components/schemas/ClientIdentityControlType" } }, - "required": ["control", "action"] + "required": ["control"] }, "IdentityPendingRequirementType": { "type": "string",