Create an Issuer
The primary product flow is the wallet-first page at /app/mint. The connected wallet calls createCapTable, becomes issuer ADMIN, and then registers the confirmed deployment with POST /issuer/register.
Wallet-first product flow
- Open
http://localhost:3000/app/mintand connect an EIP-6963 browser-extension wallet. - Enter the issuer details and submit the transaction.
- Confirm the transaction in the wallet. The caller becomes ADMIN; the configured
NEXT_PUBLIC_OPERATOR_ADDRESS, when present, receives OPERATOR. - After confirmation, the app registers the OCF issuer metadata with the API.
The bytes16 ID sent to the factory must remain paired with the UUID registered in Mongo so the poller can join the IssuerCreated event correctly.
Alternative: server-signed API flow
With a funded server/operator development key, POST /issuer/create does two things in one call:
- Calls
createCapTableon the registered factory, deploying a new beacon-proxy cap table contract whose address shows up asdeployed_to. - Inserts the OCF issuer record into MongoDB, returning the
_idyou’ll reuse for every subsequent transaction.
Required fields
| Field | Description |
|---|---|
legal_name | Issuer’s full legal name. |
formation_date | ISO date the issuer was formed. |
country_of_formation | ISO 3166-1 alpha-2 country code (US, GB, etc.). |
country_subdivision_of_formation | ISO 3166-2 subdivision (DE for Delaware, CA for California). |
initial_shares_authorized | Total authorized shares for the issuer as a string integer. |
tax_ids[], email, address, comments | OCF-shaped fields validated against the OCF schema. |
Send a POST request
Using Postman or curl, send a POST request to http://localhost:8293/issuer/create
{
"legal_name": "Transfer Agent Protocol",
"formation_date": "2022-08-23",
"country_of_formation": "US",
"country_subdivision_of_formation": "DE",
"initial_shares_authorized": "10000000",
"tax_ids": [
{
"tax_id": "88-3977591",
"country": "US"
}
],
"email": {
"email_address": "alex@plume.org",
"email_type": "BUSINESS"
},
"address": {
"address_type": "LEGAL",
"street_suite": "Empire State Building, 20 W 34th St. Suite 7700",
"city": "New York",
"country_subdivision": "NY",
"country": "US",
"postal_code": "10118"
},
"comments": []
}All fields are validated against the OCF schema.
Check the response
The response includes your new issuer with key fields:
_id: The issuer ID (you’ll need this for all subsequent API calls)deployed_to: The cap table contract address onchaintx_hash: The deployment transaction hash
If these fields are present, the API found the factory, sent the transaction, and saved the issuer.
It will look like this, with your unique _id
{
"issuer": {
"_id": "b6ca9d9c-1daa-4b30-830b-444561ef7806",
"object_type": "ISSUER",
"legal_name": "Transfer Agent Protocol",
"formation_date": "2022-08-23",
"country_of_formation": "US",
"country_subdivision_of_formation": "DE",
"tax_ids": [
{
"tax_id": "88-3977591",
"country": "US"
}
],
"email": {
"email_address": "alex@plume.org",
"email_type": "BUSINESS"
},
"address": {
"address_type": "LEGAL",
"street_suite": "Empire State Building, 20 W 34th St. Suite 7700",
"city": "New York",
"country_subdivision": "NY",
"country": "US",
"postal_code": "10118"
},
"initial_shares_authorized": "10000000",
"comments": [],
"deployed_to": "0xC1727e917a2aAa3B200C44B21a4359F5e4eBC7c0",
"tx_hash": "0x99edbf81183d22bbf286ec3e8f74d0dfc40aa1b07036de8df7d37a5d216e6d5c",
"last_processed_block": null,
"is_manifest_created": false,
"createdAt": "2026-01-01T18:25:26.078Z",
"updatedAt": "2026-01-01T18:25:26.078Z",
"__v": 0
}
}The deployed_to address is unique to your deployment—it’s derived from your wallet and transaction nonce.