Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Open and manage brokerage accounts via the Alpaca Broker API — account creation, KYC/CIP, identity & disclosures, agreements, document upload (incl. W-8BEN), account status lifecycle, and account updates/closure. Use when a developer is building onboarding, KYC, or account-management flows on Alpaca in any language.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 64% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 75% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 6% | 0% |
Create and manage end-user brokerage accounts under your firm. This is the first step of any Broker API integration: no funding, journaling, or trading can happen until an account reaches ACTIVE.
> Read alpaca-broker-integration first for base URLs, auth, and conventions. This skill assumes Broker API + HTTP Basic auth.
https://docs.alpaca.markets/docs/getting-started-with-broker-api, https://docs.alpaca.markets/docs/accountshttps://docs.alpaca.markets/reference/createaccountalpaca-docs MCP → get-endpoint title "Broker API" path /v1/accounts| Method | Path | Purpose | |--------|------|---------| | POST | /v1/accounts | Create account (submit application) | | GET | /v1/accounts | List/query accounts (returns up to 1000) | | GET | /v1/accounts/{account_id} | Get one account (AccountExtended) | | PATCH | /v1/accounts/{account_id} | Update account | | POST | /v1/accounts/{account_id}/actions/close | Close account (returns 204) | | POST | /v1/accounts/{account_id}/documents/upload | Upload owner/KYC documents (array body) | | GET | /v1/accounts/{account_id}/documents | List uploaded documents | | POST / GET | /v1/accounts/{account_id}/cip | Submit / retrieve CIP results | | GET | /v1/country-info | Supported-country data | | GET | /v1/events/accounts/status | SSE stream of account-status changes → see alpaca-broker-sse-events |
POST /v1/accounts)Four objects are required: contact, identity, disclosures, agreements. documents and trusted_contact are optional but usually needed for KYC.
json{ "contact": { "email_address": "jane@example.com", "phone_number": "+15555555555", "street_address": ["20 N San Mateo Dr"], "city": "San Mateo", "state": "CA", // required if country / country_of_tax_residence is USA "postal_code": "94401", "country": "USA" // ISO 3166-1 alpha-3 }, "identity": { "given_name": "Jane", "family_name": "Doe", "date_of_birth": "1990-01-01", "tax_id_type": "USA_SSN", // see enum below "tax_id": "666-55-4321", "country_of_tax_residence": "USA", "funding_source": ["employment_income"] }, "disclosures": { "is_control_person": false, "is_affiliated_exchange_or_finra": false, "is_politically_exposed": false, "immediate_family_exposed": false }, "agreements": [ { "agreement": "customer_agreement", "signed_at": "2026-01-02T18:09:33Z", "ip_address": "185.13.21.99" } ], "documents": [ /* OwnerDocumentUploadRequest[] — see §4 */ ], "trusted_contact": { "given_name": "Jim", "family_name": "Doe", "email_address": "jim@example.com" } }
Key field rules:
contact.street_address is an array (max 3 lines). contact.state required when country/tax-residence is USA.identity.funding_source is an array; one+ of employment_income, investments, inheritance, business_income, savings, family.tax_id_type enum is large and country-specific: USA_SSN, USA_ITIN, IND_PAN, MEX_RFC, GBR_NINO, … plus generic NATIONAL_ID, PASSPORT, DRIVER_LICENSE, OTHER_GOV_ID, NOT_SPECIFIED. Query the spec for the full list rather than hardcoding.account_type (trading|custodial|donor_advised|ira), account_sub_type (IRA: traditional|roth), enabled_assets (us_equity|us_option|crypto|ipo, default us_equity).investment_objective/investment_time_horizon/liquidity_needs/risk_tolerance moved from identity to top-level.Responses: 200 → account object · 409 email already registered · 422 invalid value · 400 malformed body.
Each entry: agreement (customer_agreement, account_agreement, margin_agreement, crypto_agreement, options_agreement), signed_at (RFC3339), ip_address (IPv4), optional revision. You must present the agreement text to the user and capture the real signing timestamp + IP — Alpaca treats these as the legal record. revision defaults to the currently-active revision if omitted.
documents[] items: document_type + (content base64 or content_data).
json{ "document_type": "identity_verification", "content": "<base64>", "mime_type": "image/jpeg", "document_sub_type": "passport" }
document_type enum includes identity_verification, address_verification, date_of_birth_verification, tax_id_verification, w8ben, w9, cip_result, and more.mime_type: application/pdf, image/png, image/jpeg — plus application/json only for w8ben.content_data as a structured W8benDocument JSON object (full_name, country_citizen, permanent_address_, date_of_birth, ip_address, timestamp, signer_full_name, …) and Alpaca renders the official form for you. This is the clean way to satisfy the tax-form requirement for non-US persons programmatically.status (and crypto_status) use the AccountStatus enum:
| Status | Meaning | |--------|---------| | ONBOARDING | Application expected, not yet submitted | | SUBMITTED | Submitted, being processed | | SUBMISSION_FAILED | Submission error | | ACTION_REQUIRED | Needs manual action (e.g. a true disclosure routes here) | | APPROVAL_PENDING | Approval in progress (documented "initial value") | | APPROVED | Approved, waiting to go active | | ACTIVE | Fully usable — funding & trading allowed | | REJECTED | Application rejected | | ACCOUNT_UPDATED | Modified by user | | ACCOUNT_CLOSED | Closed | | INACTIVE | Not enabled for the given asset |
Happy path: SUBMITTED → APPROVAL_PENDING → APPROVED → ACTIVE.
Lesson — gate every downstream op on ACTIVE. A 200 from POST /v1/accounts does not mean tradable. Subscribe to account-status SSE events (or poll GET /v1/accounts/{id}) and only enable funding/journals/trading once status == ACTIVE. Trying to journal or trade into a non-active account fails.
kyc_results on the account object carries reject/accept/indeterminate categories (KYCResultType values like IDENTITY_VERIFICATION, TAX_IDENTIFICATION, ADDRESS_VERIFICATION, WATCHLIST_HIT, COUNTRY_NOT_SUPPORTED, OTHER) plus additional_information. summary is pass/fail (internal only).POST /v1/accounts/{id}/cip with a CIPInfo body (provider_name, kyc, document, photo, identity, watchlist sub-results). Sub-check results are clear/consider.WATCHLIST_HIT / COUNTRY_NOT_SUPPORTED require no user action — Alpaca handles them manually.USA, PHL, …) — strip any UI decoration (flags/emoji, display names) and validate against GET /v1/country-info. Garbage in country/country_of_tax_residence is a common 422.signed_at and ip_address must reflect the actual user action, not server time / a placeholder.account_id immediately, then drive UI off the status events, not the create response.409 on duplicate email is your friend — look up the existing account rather than retrying creation. Store your local user↔account_id mapping before the network call so a timeout doesn't orphan an account.POST .../actions/close, you must liquidate all positions and withdraw all cash. The account record is not deleted — it goes ACCOUNT_CLOSED.Related skills: fund the account → alpaca-broker-funding-transfers; move cash in via the firm sweep → alpaca-broker-journals; trade → alpaca-broker-trading-orders; track status in real time → alpaca-broker-sse-events.
Other measured skills in the registry, with their headline benchmark lift.