API reference
Everything an assistant can do through Tenacap is a capability, and every capability is one REST operation. This page is generated from the same list the MCP server publishes and the OpenAPI document describes, so the three cannot disagree.
You need an API token from Settings → API tokens (see Connect your AI assistant). Send it as Authorization: Bearer tnc_…. A token is minted with one or more scopes - read, model, write:propose - and each operation below names the one it needs. Every operation also needs read, the scope the door checks, as the MCP endpoint does. No scope commits a write: a write from a token is a proposal that a person confirms in the web app.
Calling an operation
Every operation is POST https://www.tenacap.com/api/v1/{name} with a JSON object body: the operation’s input, plus company_id naming the company the call is scoped to. A token bound to one company may leave company_id out and the binding fills it in; if it names any other company, the answer is not_found. Three operations act on your account rather than one company and take no company_id: list_companies, and the two that create a company, create_company and create_company_from_import, which take a workspace_id instead.
curl -X POST https://www.tenacap.com/api/v1/get_company \
-H "Authorization: Bearer tnc_…" \
-H "Content-Type: application/json" \
-d '{"company_id": "<your company id>"}'The envelope
Every successful answer has the same shape:
summary- one line, in ownership terms, with the figures in it. An assistant is told to quote it rather than paraphrase it.data- the operation’s output, validated against its schema before it is sent. Share counts and cents are decimal integer strings, never numbers.sources- the records the figures came from, as{ type, id }pairs. Never empty for a read or a model.asOf- the server clock at compute time, ISO-8601.capTableHash- the ledger tip hash, when the answer derives from the ledger.version-v1.
Errors
A refusal is { code, message, help?, details? }. code is one of invalid_input (400), insufficient_scope, insufficient_role or confirm_only (403), not_found (404, and a company outside your workspace is not found, never forbidden), unsupported_instrument (422), precondition_blocked or needs_review (409), rate_limited (429) and internal (500). help is a Help center slug; details carries the validation issues for invalid_input. A missing or revoked token is a 401 before any of this, and a token without read is refused at the door with { error: “insufficient_scope”, scope }. A token that has read but not the scope an operation’s kind needs gets insufficient_scope in the shape above, the same answer the MCP tool gives.
Operations
170 operations today. More arrive as capabilities land; each new one appears here, in the MCP tool list and in the OpenAPI document on the same day, because all three read the same registry.
Read
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/get_company | read | VIEWER | The company record: legal name, jurisdiction, entity type, incorporation date, authorized shares, and how many stakeholders, share classes, securities and ledger transactions it has. Getting started |
POST /api/v1/get_security | read | VIEWER | One share holding as the ledger replays it: holder, share class, quantity, price per share, issue date, status and certificate number, plus the link to its certificate PDF. Managing your cap table |
POST /api/v1/list_securities | read | VIEWER | Every share holding as the ledger replays it (holder, share class, quantity, price, issue date, status and certificate number), optionally filtered by status, holder or share class, with the outstanding total; and under convertibles every outstanding SAFE and convertible note with its id, holder, amount, cap, discount and post- or pre-money basis, the id model_priced_round, edit_safe, edit_convertible_note and cancel_instrument take. Managing your cap table |
POST /api/v1/list_grants | read | VIEWER | Every option grant, RSU and warrant with its vesting as of today (granted, vested, exercised, unvested, outstanding), plus the rollup by holder and by plan that the options tab shows. Optionally filtered by kind, holder or status. Each grant carries what is printed on its agreement: holderName, originalQuantity, grantDate, strikePrice and, when imported, the source platform's grant id as sourceGrantId (Pulley "ES-12"), which is how request_document_upload matches agreement PDFs to grants. Options, grants & vesting |
POST /api/v1/get_grant | read | VIEWER | One option grant, RSU or warrant: size, strike, dates, status and its vesting as of today (vested, unvested, exercised, forfeited), with the holder’s option rollup. Options, grants & vesting |
POST /api/v1/list_vesting_templates | read | VIEWER | Lists the company’s saved vesting schedule templates: named presets (e.g. "Standard 48/12", "Advisor 24/0") that pre-fill the cliff, total, frequency and rounding fields on a grant form, plus an optional single- and/or double-trigger acceleration term a template may carry as a label (the product does not evaluate whether a trigger fired and does not apply it to any grant’s computed vesting). A template is a starting point: picking one does not stop the fields from being edited, and editing or deleting a template never changes a grant that already used it. Options, grants & vesting |
POST /api/v1/get_vesting_schedule | read | VIEWER | A stored vesting schedule (standard cliff-and-monthly or custom milestones, with any acceleration, pause and resume events) and how much of it has vested as of a date. Vesting calendar |
POST /api/v1/get_audit_trail | read | EDITOR | The company’s tamper-evident audit trail, newest first: who did what to which record and when, with the before/after values where recorded and the chain hash. Paginated; optionally one category (ledger, documents, signatures, settings, access). Trust & security |
POST /api/v1/list_documents | read | VIEWER | The documents attached to the company’s grants, holdings, board approvals, plans and stakeholders, and every e-signature request with its status and signer progress. Metadata and authenticated download links only; never a file body. Documents & e-signature |
POST /api/v1/whoami | read | EMPLOYEE | Who the caller is to this company: session or token, the token scopes, the workspace, the company, and the membership role. Contains no personal data. Roles & permissions |
POST /api/v1/list_companies | read | EMPLOYEE | The companies this connection can reach, with each company id, legal name, workspace and your role there, and the workspaces themselves, including an empty one, which is where a first company would be created. Call it first when you do not know a company_id; every other tool needs one. If this connection is pinned to one company, the summary and `boundTo` say so: a company made afterwards is invisible until the person reconnects and picks another company or the whole workspace. Connect your AI assistant |
POST /api/v1/get_cap_table | read | VIEWER | The cap table as the ledger replays it: share classes with authorized, issued and outstanding counts, every outstanding holding, and each holder’s fully-diluted ownership in basis points over outstanding economic shares plus granted options, outstanding RSUs, unexercised warrants and the unallocated pool. Share counts are decimal strings. Optionally as of a past date. Managing your cap table |
POST /api/v1/list_stakeholders | read | VIEWER | A page of the company’s stakeholders (people, entities and trusts) in the order they were added, each with contact fields, whether a tax id is on file, portal access status, and a holdings summary: outstanding shares by class and fully-diluted ownership in basis points. Cursor-paginated; tax ids and bank details are never returned. Importing stakeholder emails |
POST /api/v1/get_stakeholder | read | VIEWER | One stakeholder: contact fields, whether a tax id is on file, termination status, portal access status, and their holdings (outstanding shares by class and fully-diluted ownership in basis points). Tax ids and bank details are never returned. Importing stakeholder emails |
POST /api/v1/get_voting_power | read | VIEWER | Per-holder, per-class voting power (shares × votingRatio), optionally filtered to one or more share classes, and a majority calculator over three threshold types: a majority of outstanding voting shares (DGCL §228(a)), a single class voting separately (DGCL §242(b)(2)), or preferred as one class at a typed-in percentage ("Requisite Holders", NVCA COI §3.3). Board members and company admins only, since vote shares reveal control structure. Share counts and voting power are decimal strings. Voting |
POST /api/v1/get_board | read | EDITOR | The board: the voting-board roster (directors, e-mail, title, active or not), every recorded board approval with its status and the status of its latest consent signature request, and each share class holding treasury shares the board has not yet retired. Board approvals |
Compliance
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/check_equity_health | read | VIEWER | The equity-health grade (A–D) and score, with each scored check (current 409A, failed when it has lapsed or a priced round closed after its date; 409A coverage on grants, 83(b) timeliness, grant signatures, board approvals) as pass, warn or fail, and the facts each check was decided from. When an option plan is on the stakeholder list as a person holding nothing, a "plan-listed-as-person" warning names it; remove it with delete_stakeholder. The same grade the company overview shows and the grade-drop alert watches. Cap-table health signals |
POST /api/v1/get_409a_status | read | VIEWER | The valuation of record in force today: its fair market value per share, how it was determined (409A appraisal, board determination or other), its age in days, when it expires and whether it is stale, including stale because a priced round closed after its date. When none is in force, whether one lapsed or none was ever recorded. Compliance & tax |
POST /api/v1/get_rule_701_headroom | read | VIEWER | Rule 701 exemption usage over the trailing twelve months: the dollar value of options offered, the cap that applies ($1M, 15% of total assets or 15% of the class outstanding), the headroom left, and the grants counted or skipped for lack of a valuation at their grant date. The same figures the Options and 409A pages show. Compliance & tax |
POST /api/v1/check_qsbs_eligibility | read | VIEWER | A stakeholder’s QSBS (IRC §1202) position, holding by holding: acquisition date, the five-year mark and days remaining, the applicable exclusion percentage, the $50M / $75M gross-assets test, the active-business test, eligibility, basis and the exclusion cap, with the caveats a reader must weigh. The same analysis as the QSBS memo PDF. Informational, not tax advice. QSBS (§1202) |
POST /api/v1/calculate_asc718_expense | read | EDITOR | ASC 718 stock-compensation expense through a date: per-grant Black-Scholes fair value, expense recognized to date and unrecognized, the monthly and annual recognition buckets, and the grants excluded for want of a 409A or an assumption set at their grant date. The same figures as the ASC 718 CSV download. ASC 718 stock-comp report |
POST /api/v1/get_form3921_status | read | EDITOR | Form 3921 (IRC §6039) status for every reportable option grant: issued, due (an exercised ISO lot past its January 31 (or next-business-day) furnish deadline with no form issued), upcoming, prior platform (exercised and imported from a year before the company joined Tenacap: confirm the prior provider furnished it), or not applicable (NSO or never exercised), with the lots still owed a form. Imported exercises count like ones recorded here. The same column the Option Holdings page shows. Compliance & tax |
POST /api/v1/get_de_franchise_tax | read | VIEWER | Delaware franchise tax for a tax year: the Authorized Shares and Assumed Par Value Capital methods, which one is cheaper, the annual-report fee, the total due and its deadline, and the inputs it was computed from (authorized and issued shares, par values, gross assets), or the flat annual tax for an LLC. The same figures as the Delaware filings page and its report. Delaware franchise tax |
POST /api/v1/list_deadlines | read | VIEWER | Every open compliance deadline within a horizon (default 30 days), overdue ones included: 83(b) filing windows, the 409A valuation expiry, post-termination exercise windows, the Delaware franchise or LLC tax date, Form 3921 furnish dates and, for a BVI company, the register-of-members filing (30 days after a change to who holds shares) and the annual government fee, from the same derivation the reminder emails are sent from. Optionally filtered by kind. Compliance & tax |
Model
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/model_priced_round | model | VIEWER | Model a priced round on the live cap table without recording anything: the round price (pre-money valuation over fully-diluted shares after the SAFEs convert plus the pool increase, the term-sheet convention), the new shares, each SAFE’s conversion at the best of its cap price, its discounted round price and the round price, an option-pool increase sized so the unissued pool plus the increase is the target fraction of post-money fully diluted (a pre-money shuffle), and every holder’s ownership before and after in basis points. Fully diluted counts outstanding shares, granted options and the unissued pool; a post-money SAFE cap is spread over the YC Company Capitalization and a pre-money cap over the pre-round count plus the pool increase (the original YC form). This is what the scenario page computes. Every outstanding recorded SAFE converts unless safes lists which (list_securities names them under convertibles). Every outstanding convertible note converts too (or those named in notes), at principal plus interest to roundDate (today when absent), through the same cap, discount and pre/post-money rules close_priced_round uses; a note that does not record its cap basis is read as pre-money and says so. Money is dollars as strings; a recorded SAFE with an MFN provision is refused. Scenario modeling |
POST /api/v1/calculate_dilution | model | VIEWER | Ownership before and after one hypothetical issuance on the live cap table, without recording anything: give a share count, or an investment in dollars at a dollars-per-share price (the share count is floored), and optionally the existing stakeholder who receives the shares. Returns every holder’s shares and ownership in basis points before and after, on two bases: outstanding shares only (the *OutstandingBasisPoints fields), and fully diluted as the cap-table page counts it, outstanding plus granted options plus outstanding RSUs plus unexercised warrants plus the unallocated pool (the *FullyDilutedBasisPoints fields). No option pool change, no SAFE conversion. preFdShares, postFdShares, beforeBasisPoints and afterBasisPoints are deprecated aliases of the outstanding figures. For a full round with SAFEs and a pool top-up use model_priced_round. Scenario modeling |
POST /api/v1/model_exit_waterfall | model | VIEWER | Model how an exit at a given dollar value is distributed across the live cap table without recording anything: each preferred class takes its liquidation preference (multiple × invested basis, plus cumulative dividends accrued to today) or converts to common when that pays more, participating classes share the residual up to their cap, outstanding options and warrants net-exercise when in the money, and an unconverted SAFE or note takes the greater of its cash-out and converting at its valuation cap; a note’s cash-out is (principal + accrued interest) × its change-of-control multiple, 1× when none is recorded. Returns the payout order (notes repaid, preferred preferences, SAFEs cashed out, residual), proceeds per class, per option or warrant, per convertible and per stakeholder, and for each class and convertible the terms used, both sides of its greater-of decision and any term assumed rather than recorded, in cents as strings. Refused when a share class’s stored rights cannot be read or no economic shares are outstanding. Exit waterfall |
POST /api/v1/size_option_pool | model | VIEWER | How many shares to add to the option pool so the unallocated reserve is a target percentage of post-top-up fully diluted (outstanding shares plus granted options plus outstanding RSUs plus unexercised warrants plus the unallocated pool): add = (target × fully diluted − unallocated) ÷ (1 − target), floored, or zero when the pool already meets the target. The target is a percentage string ("10" is 10%). Informational, not advice. Founder calculators |
POST /api/v1/shares_for_target_percent | model | VIEWER | How many shares to grant so the grantee owns a target percentage of post-grant fully diluted (outstanding shares plus granted options plus outstanding RSUs plus unexercised warrants plus the unallocated pool), as a pre-money shuffle that dilutes existing holders: shares = target ÷ (1 − target) × fully diluted, floored. Also says whether the unallocated pool can cover it. The target is a percentage string ("1" is 1%). Informational, not advice. Founder calculators |
Securities
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/grant_option | write:propose | EDITOR | Grant stock options (ISO or NSO) to a stakeholder from an option plan, with an optional inline vesting schedule and board approval date. The grant is numbered, priced under the valuation in force on the grant date, and drawn down from the plan. As a proposal it reports the 409A in force and its age (a blocker when there is none, a warning past twelve months, and a warning when a priced round closed after its valuation date), the ISO $100k projection, the plan headroom and the Rule 701 headroom, with a diff of ownership over outstanding shares treating the grant as issued (as calculate_dilution shows it; unexercised options and the unallocated pool are not in the base). An optional fromPromisedOptionId converts an open promised option into this grant: the promise is marked granted in the same write, so it is never counted twice (spec-0098). Nothing is written until a person confirms. Options, grants & vesting |
POST /api/v1/grant_rsu | write:propose | EDITOR | Grant restricted stock units to a stakeholder: a promise to deliver shares on vesting, with no purchase price and no shares issued at grant; optionally under an option plan (optionPoolId), which the units draw down like an option grant, optionally double-trigger (settles on a liquidity event) and with an inline vesting schedule. As a proposal it reports the plan headroom and shows ownership of outstanding shares before and after, treating the units as settled (as calculate_dilution shows it). Outstanding RSUs, vested or unvested, are counted in fully-diluted ownership, like unexercised options. An optional fromPromisedOptionId converts an open promised option into this grant: the promise is marked granted in the same write, so it is never counted twice (spec-0098). Nothing is written until a person confirms. Options, grants & vesting |
POST /api/v1/cancel_grant | write:propose | EDITOR | Cancel an outstanding option grant and return its unexercised options to the plan it drew from; options already exercised are issued shares and stay counted against the plan. As a proposal it refuses a grant that is not outstanding, warns when a grant notice is still out for signature, and shows the plan’s unallocated shares before and after. Nothing is written until a person confirms. Options, grants & vesting |
POST /api/v1/create_phantom_plan | write:propose | ADMIN | Proposes a phantom equity plan: a plan that grants phantom stock (full-value units) or stock appreciation rights, which are promises to pay money tied to the value of shares, not shares. Its size is in units and uses none of the authorized shares. A plan paid in shares must name the option plan whose reserve it draws on. countInFullyDiluted decides whether its cash-settled units are counted in fully diluted (off by default; stock-settled units always count). A person with the ADMIN role confirms it; nothing is written until then. Phantom equity & SARs |
POST /api/v1/edit_phantom_plan | write:propose | ADMIN | Proposes a change to a phantom equity plan’s recorded terms: name, size in units, default settlement, the option plan a stock-settled plan draws on, board date, and countInFullyDiluted, the switch that counts its cash-settled units in fully diluted. The proposal shows fully diluted before and after when the switch changes. A size below what the plan has granted is refused. A person with the ADMIN role confirms it. Phantom equity & SARs |
POST /api/v1/grant_phantom | write:propose | EDITOR | Grant phantom stock (full-value units) or stock appreciation rights to a stakeholder: a promise to pay money tied to the value of shares, not shares. A cash-settled award issues no shares and uses none of the authorized shares; one paid in shares must be under a phantom plan that draws on an option plan, whose available shares it uses one unit to one share. Takes units (or a percentage of fully diluted), a base price for a SAR, the settlement, when it pays, and an inline vesting schedule. As a proposal it warns when a SAR’s base is below the 409A value in force and shows fully diluted before and after when the award is counted. Nothing is written until a person confirms. Phantom equity & SARs |
POST /api/v1/edit_phantom_award | write:propose | EDITOR | Proposes a correction to an outstanding phantom award’s recorded terms: units, base price, settlement, when it pays, what a unit is worth at a sale, grant, board and expiration dates, the share class it tracks, and notes. A correction, not a repricing: a lower base on a stock appreciation right is a new grant for §409A, recorded as a cancellation and a new grant. The diff shows each changed field before and after. Nothing is written until a person confirms. Phantom equity & SARs |
POST /api/v1/cancel_phantom_award | write:propose | EDITOR | Proposes cancelling or forfeiting an outstanding phantom award (phantom stock or a stock appreciation right) from a date. Its units go back to its phantom plan, and a stock-settled award’s units go back to the option plan it drew on. No shares move; the proposal shows the plan’s available units and fully diluted before and after. Nothing is written until a person confirms. Phantom equity & SARs |
POST /api/v1/record_phantom_payout | write:propose | EDITOR | Proposes recording a cash payment the company already made on a phantom award: the date, the units it settles, the value per unit and the cash paid. Money does not move through Tenacap. Payments that settle every unit mark the award paid. To settle in shares, use settle_phantom_in_shares. Nothing is written until a person confirms. Phantom equity & SARs |
POST /api/v1/list_phantom_awards | read | VIEWER | Lists the company’s phantom equity plans and awards (phantom stock and stock appreciation rights): each plan’s units authorized, granted and available and whether it is counted in fully diluted, and each award’s holder, units, base price, settlement, when it pays, vested units and payouts. These are promises to pay money, not shares. Outstanding awards by default; status ALL adds paid, cancelled and forfeited ones. Phantom equity & SARs |
POST /api/v1/get_phantom_award | read | VIEWER | Reads one phantom award (phantom stock or a stock appreciation right) by id, with its plan: units, base price, settlement, when it pays, vested units, status, payouts and whether it is counted in fully diluted. A promise to pay money, not a share. Phantom equity & SARs |
POST /api/v1/record_promised_option | write:propose | EDITOR | Records a promised option: a commitment to grant options to a holder that has not been papered as a grant yet. Not a security; nothing is issued and no authorized shares are used. Takes the holder, units, the option plan it will draw from once granted (optional), the date the offer was made, and a note. Counted in the YC post-money SAFE’s Company Capitalization once recorded, not in the cap-table page’s headline fully diluted figure. Nothing is written until a person confirms. SAFEs & convertibles |
POST /api/v1/withdraw_promised_option | write:propose | EDITOR | Withdraws a promised option when the offer falls through: the candidate declined or the role was cut. The record is kept, marked withdrawn, and drops out of the YC post-money SAFE’s Company Capitalization from this moment; never deleted. Refuses a promise already granted or withdrawn. Nothing is written until a person confirms. SAFEs & convertibles |
POST /api/v1/list_promised_options | read | VIEWER | Lists the company’s promised options: commitments to grant options to a holder, not yet a security. Each row’s holder, units, plan (if any), status and dates. Open (PROMISED) promises by default; status ALL adds granted and withdrawn ones. promisedUnits is the sum the YC post-money SAFE’s Company Capitalization counts. SAFEs & convertibles |
POST /api/v1/get_promised_option | read | VIEWER | Reads one promised option by id: holder, units, plan (if any), status and dates. A commitment to grant options, not a security. SAFEs & convertibles |
POST /api/v1/issue_shares | write:propose | EDITOR | Propose issuing new shares of an authorized share class to an existing stakeholder at a price per share on an effective date. The proposal shows every holder’s outstanding shares and ownership before and after, and is blocked when the class lacks unissued authorized headroom. Nothing is recorded until a person with the Editor role confirms it in the web app; confirming writes one ISSUE_SHARES ledger transaction with a certificate number. Managing your cap table |
POST /api/v1/issue_founder_stock | write:propose | EDITOR | Propose issuing restricted stock to a founder or early employee: shares of an authorized class at a price per share, optionally a vesting schedule (standard cliff and months, or custom milestones; omit it for stock fully vested at purchase) and, with vesting, a Section 83(b) election to track. Optionally from an equity incentive plan (optionPoolId) on the same class, which the shares draw down one for one and whose reserve on the ledger they release. The proposal shows every holder’s outstanding shares and ownership before and after, and is blocked when the class lacks unissued authorized headroom or the plan lacks available shares. Confirming writes the ledger rows with the vesting schedule, the RSA instrument the purchase agreement renders from, and the 83(b) record, together; sending the agreement for signature is done in the web app. Restricted stock & 83(b) |
POST /api/v1/transfer_shares | write:propose | EDITOR | Propose transferring some or all of an outstanding lot from one stakeholder to another at a price per share on an effective date, with the reason it moved (sale, gift, death and so on), which decides whether the transferee keeps QSBS status. The proposal shows each holder’s outstanding shares and ownership before and after; it is blocked when the lot is not the sender’s, is not outstanding, or holds fewer shares than asked, and warns when a signature request on the lot is still out. Confirming writes one TRANSFER_SHARES ledger transaction and numbers the new certificate. Managing your cap table |
POST /api/v1/settle_phantom_in_shares | write:propose | EDITOR | Propose settling units of a phantom award or SAR in shares on a date, at the fair market value of a share then. A SAR settles net: the holder gets shares worth the growth over the base price, and the fraction of a share in cash; full-value units deliver one share each. The shares come from the equity plan the phantom plan draws on: confirming releases them from the plan’s reserve and issues them to the holder in one ledger write, and records the payout. Nothing is written until a person confirms. Phantom equity & SARs |
POST /api/v1/set_transfer_reason | write:propose | ADMIN | Propose recording why an existing share transfer happened (sale, gift, death, divorce, a move to the holder’s own trust, and so on) when it was recorded without a reason. QSBS reads it: a gift or death carries the giver’s holding period and status over (IRC §1202(h)), a sale ends QSBS for the buyer (§1202(c)(1)). Set once; the ledger row is not changed. QSBS (§1202) |
POST /api/v1/set_rsa_plan | write:propose | ADMIN | Propose recording which equity incentive plan an existing grant of restricted stock (an RSA) came from, or that it came from no plan (optionPoolId null). Restricted stock granted under a plan uses that plan’s shares one for one, so tying it lowers what the plan has available and, when the plan’s reserve is on the ledger, releases the shares from it; untying does the reverse and is blocked when the share class has no room to take them back. Blocked for anything but outstanding restricted stock, a plan on another share class, or a plan without enough available shares. The share issuance itself is not changed. Nothing is written until a person confirms. Restricted stock & 83(b) |
POST /api/v1/record_buyback | write:propose | EDITOR | Propose the company repurchasing some or all of one outstanding lot from its holder at a price per share on an effective date; the shares are retired. The proposal shows every holder’s outstanding shares and ownership before and after; it is blocked when the lot is not the holder’s, is not outstanding, or holds fewer shares than asked, and warns when a signature request on the lot is still out. Confirming writes one REPURCHASE_SHARES ledger transaction. A buyback across several holders is done in the web app. Share buy-backs |
POST /api/v1/cancel_shares | write:propose | EDITOR | Propose cancelling one outstanding lot in full on an effective date, with an optional reason recorded on the ledger. The proposal shows every holder’s outstanding shares and ownership before and after; it is blocked when the lot is not the holder’s or is not outstanding, and warns when a signature request on the lot is still out. Confirming writes one CANCEL_SHARES ledger transaction; the lot stays on the ledger as CANCELLED. Managing your cap table |
POST /api/v1/record_exercise | write:propose | EDITOR | Propose recording an option exercise: a number of options from an outstanding grant become the same number of shares of the chosen class at the grant’s strike, on an effective date. The proposal shows the holder’s exercised and unexercised options and their shares before and after; it is blocked when the quantity exceeds what the grant has left, and warns when it exceeds what has vested by that date (an early exercise: the lot is restricted and an 83(b) election is seeded). On a grant that does not allow early exercise, exercising more than is vested and not yet exercised is blocked instead. Confirming writes one EXERCISE_OPTION ledger transaction with the pool draw-down and, on an early exercise, the restricted lot’s vesting and 83(b) record. Option Holdings |
POST /api/v1/list_exercise_requests | read | EDITOR | Holders’ requests, from their portal, that the company record an exercise of their option grant: who asked, which grant, how many options and when, and the status. Lists pending requests by default (the queue on the Update cap table page); ALL includes fulfilled and dismissed ones with when and by whom they were closed. Optionally filtered by holder or grant. Each id is the requestId fulfill_exercise_request and dismiss_exercise_request take. Stakeholder portal |
POST /api/v1/fulfill_exercise_request | write:propose | EDITOR | Propose recording the option exercise a holder asked for from their portal, and closing their exercise request as fulfilled, as one write. The grant is the request’s; the quantity defaults to what the holder asked for. The proposal is record_exercise’s (the holder’s exercised and unexercised options and shares before and after, blocked past what the grant has left or, on a grant that does not allow early exercise, past what has vested; a warning on an early exercise) plus the request going from pending to fulfilled; it is blocked when the request is not this company’s or is already closed, and warns when the quantity differs from the request. Confirming writes one EXERCISE_OPTION ledger transaction and closes the request in the same database transaction, so neither happens without the other. Stakeholder portal |
POST /api/v1/dismiss_exercise_request | write:propose | EDITOR | Propose closing a holder’s exercise request without recording an exercise: a withdrawn ask, a grant since cancelled, or a request the company will not act on. Nothing changes on the cap table; the holder sees the request closed and may raise a new one. The proposal shows the request going from pending to dismissed and is blocked when the request is not this company’s or is already closed. To record the exercise instead, use fulfill_exercise_request. Stakeholder portal |
POST /api/v1/add_share_class | write:propose | ADMIN | Proposes a new share class (common or preferred) with its authorized share count, seniority, optional par value and rights, recorded as an AUTHORIZE_SHARES ledger entry. The proposal reports the authorized total before and after and blocks on a name or seniority already in use. A person with the ADMIN role confirms it in the web app; nothing is written until then. Managing your cap table |
POST /api/v1/increase_authorized_shares | write:propose | ADMIN | Propose recording a charter amendment (DGCL §242) that raises one share class’s authorized shares to a new total, effective on the date the certificate of amendment was filed, with an optional note. Give the new TOTAL the amended certificate states, not the increase. The proposal shows the class’s authorized count and the shares still free to issue, before and after; it is blocked when the total is not more than today’s (a decrease is a different amendment). Confirming writes one AUTHORIZE_SHARES ledger transaction. It records an amendment already adopted and filed; it does not adopt one. Managing your cap table |
POST /api/v1/create_option_pool | write:propose | ADMIN | Proposes a new option plan (pool) with its authorized share count and, optionally, the date the board approved it. The proposal reports the pool as a share of fully diluted ownership and shows the unallocated pool before and after. Creates only; an existing plan's size or name is changed with update_option_plan. A person with the ADMIN role confirms it; nothing is written until then. Options, grants & vesting |
POST /api/v1/attach_vesting | write:propose | EDITOR | Proposes a vesting schedule for an outstanding option grant or an issued share lot that has none: STANDARD (cliff and total months, monthly, quarterly or annual) or CUSTOM (dated milestones as fractions of the total). startDate is the vesting commencement date, not today. rounding is how a fractional vested count becomes whole shares: FLOOR (the default) or NEAREST, whichever the agreement says. The proposal warns when a schedule already exists and shows the shares vested as of today before and after. A person with the EDITOR role confirms it; nothing is written until then. Vesting calendar |
POST /api/v1/record_vesting_event | write:propose | EDITOR | Propose recording a vesting event on an existing vesting schedule: ACCELERATION (a number of shares vests early on a date, for example after a change of control), PAUSE (a leave of absence starts, and a standard schedule stops counting months) or RESUME (the leave ends). It records an event that already happened; it does not decide whether an acceleration clause was triggered. The proposal shows the shares vested and unvested on the schedule before and after, as of the event date and today, and warns when an acceleration is more than is still unvested or a pause or resume has no partner. A person with the EDITOR role confirms it; nothing is written until then. Events are never edited or deleted. Vesting calendar |
POST /api/v1/complete_reported_vesting | write:propose | EDITOR | Propose completing the vesting of an imported share holding that came in with only a reported vested figure and no schedule: attach a STANDARD (cliff and total months, monthly, quarterly or annual) or CUSTOM (dated milestones) schedule over the holding’s reported total, so vesting is computed going forward instead of shown as imported. The schedule takes the same shape as attach_vesting. startDate is the vesting commencement date. The proposal shows the shares vested as of today before (the reported figure) and after, and warns when the schedule would show fewer vested than were reported. A person with the EDITOR role confirms it; nothing is written until then. Vesting calendar |
POST /api/v1/resolve_vesting_divergence | write:propose | EDITOR | Propose the answer for an imported option grant whose reported vested figure did not match its vesting schedule: STOPPED (vesting stopped on the reported date, so vested stays at the reported figure) or RESUMED (vesting paused and has resumed on the original schedule, so nothing computed changes and the question is closed). Only a grant whose question is still open can be answered, and an answer is not undone here. The proposal shows the shares vested and unvested as of today before and after. A person with the EDITOR role who knows what happened confirms it; nothing is written until then. Vesting calendar |
POST /api/v1/save_vesting_template | write:propose | ADMIN | Propose creating a vesting schedule template (omit id) or editing an existing one (give its id): a name plus cliff months, total months, frequency and rounding, the same fields every grant form already has, plus an optional single- and/or double-trigger acceleration term (a percentage, and for double-trigger a window in months). The template pre-fills those fields when picked; it is a starting point, not a link, so editing or deleting it later never changes a grant that already used it. The acceleration term is recorded as a label; the product does not evaluate whether a trigger fired and does not apply it to any grant’s computed vesting. Blocked on a cliff longer than the total, a name already used by another template in this company, a percentage outside 1-100, or a double-trigger percentage given without its window (or the reverse). A person with the ADMIN role confirms it. Options, grants & vesting |
POST /api/v1/delete_vesting_template | write:propose | ADMIN | Propose deleting a vesting schedule template by id. Existing grants that used this template keep their own cliff, total and frequency. Deleting the template only removes it from the picker; nothing is recomputed and no grant is affected. A person with the ADMIN role confirms it. Options, grants & vesting |
POST /api/v1/edit_grant | write:propose | EDITOR | Propose changing an outstanding option grant’s strike price, expiration date or early-exercise permission. Quantity, type and plan cannot be edited (cancel and re-grant instead). The proposal shows each field before and after, and warns when the new strike is below the 409A value on the grant date, when an ISO would run past ten years, when a strike change is a modification for ASC 718, and when a grant notice was sent or signed on the old terms. A person with the EDITOR role confirms it; the old terms stay in the change log. Options, grants & vesting |
POST /api/v1/lapse_grant | write:propose | EDITOR | Propose recording that a departed holder did not exercise their options before the post-termination exercise window closed, so the grant lapses: it is marked expired and its shares return to the option plan. It is refused while the window is still open or when the holder has no departure recorded, and it records an answer a person gives; if the holder did exercise, record the exercise instead. The proposal shows the options outstanding and the plan’s unallocated shares before and after. A person with the EDITOR role confirms it. Options, grants & vesting |
POST /api/v1/cancel_instrument | write:propose | EDITOR | Propose cancelling an outstanding SAFE, convertible note, warrant or RSU grant, for example a SAFE that was never funded. An option grant is handled as cancel_grant handles it. It is refused for an instrument that already converted, was exercised, or is cancelled or expired, and for restricted stock, whose shares are cancelled with cancel_shares. The proposal shows the convertible principal, RSUs, warrants or plan shares before and after, and warns when a SAFE is out for signature. A person with the EDITOR role confirms it. Managing your cap table |
POST /api/v1/record_iso_disposition | write:propose | EDITOR | Propose recording a sale of shares from an exercised ISO lot: the lot, the number of shares, the sale price and the date. The proposal says whether the sale is qualifying (more than 2 years from grant and 1 year from exercise) or disqualifying, with the ordinary income and capital gain it creates, figured as the compliance page does. It is refused for a lot that is not an exercised ISO, a sale dated before the exercise, or more shares than the lot has left. The figures are estimates, not tax advice. A person with the EDITOR role confirms it. Compliance & tax |
POST /api/v1/update_share_class | write:propose | ADMIN | Propose renaming a share class, changing the par value on record (null records it as no-par), or entering its economic terms (preference multiple, participation, dividend, antidilution, votes per share) as the charter states them. Entering a term confirms it: Tenacap stops calling it assumed. Authorized shares are changed with increase_authorized_shares; type and seniority are not editable. A par value is a term of the certificate of incorporation, so the proposal warns that changing it is a charter amendment with a separate vote of the class (DGCL §242(b)), that shares issued afterwards must be paid for at no less than the new par (§153(a)), and, for a Delaware corporation, shows the franchise tax before and after. It records the charter’s terms; it does not adopt an amendment. A person with the ADMIN role confirms it. Managing your cap table |
POST /api/v1/confirm_share_class_terms | write:propose | ADMIN | Propose confirming that a preferred share class’s economic terms, as Tenacap holds them, match the certificate of incorporation: the liquidation preference multiple, participation, dividend, antidilution protection and votes per share. Use it when an import or the add form assumed terms (get_cap_table shows termsSource ASSUMED and which terms) and the founder says they are right. Nothing about the terms changes; to correct a term use update_share_class. A person with the ADMIN role confirms it. Managing your cap table |
POST /api/v1/update_option_plan | write:propose | ADMIN | Propose resizing or renaming an existing option plan, changing its board-approval date, or tying it to the share class it commits. Give the plan’s new TOTAL authorized shares. The proposal shows the plan’s authorized, granted and unallocated shares and the class’s shares free to issue, before and after. It is blocked when a reduction would leave the plan smaller than what it has already granted (outstanding options and RSUs plus shares issued from it), and when an increase would not fit the shares the charter still leaves free (DGCL §161). It records the new size, not the board and stockholder approval of it. A person with the ADMIN role confirms it. Options, grants & vesting |
POST /api/v1/retire_treasury_shares | write:propose | ADMIN | Propose the board retiring treasury shares of one class (DGCL §243): shares the company bought back and still holds, which stay issued until the board retires them, then return to authorized and unissued. Takes the class, the number of shares (at most its treasury balance), the resolution date and an optional note. The proposal shows the class’s issued, treasury and unissued counts before and after; no holder’s shares change. Confirming writes one RETIRE_SHARES ledger transaction and a treasury-retirement board approval together; that approval cannot later be set back to draft. An ADMIN confirms it. Board approvals |
POST /api/v1/reverse_transaction | write:propose | ADMIN | Propose reversing one ledger transaction recorded in error, with a required reason. The ledger is append-only: the original row stays, and a new REVERSE row makes the cap table read as if it had never been recorded. The proposal shows every holder’s outstanding shares and ownership before and after. It is blocked when the transaction is not this company’s, is itself a reversal, was already reversed, or a later transaction depends on it (reverse that one first); in this release, transactions recorded since the ledger began numbering its own entries are refused as not yet available. It warns when the transaction has records outside the ledger (a grant’s exercise, a plan’s size, a vesting schedule) that the reversal leaves as they are. A person with the ADMIN role confirms it in the web app; nothing is written until then. Managing your cap table |
POST /api/v1/build_cap_table | write:propose | ADMIN | Propose building a new company’s first cap table in one step, the way the web app’s "build by hand" wizard does: the common share class with its authorized shares and par value, each founder with their shares (bought at par; issued outright unless their stock purchase agreement gives a vesting schedule, which you then state), an option plan of a size you state, and any SAFEs already signed. Only for a company with no cap table yet (after create_company); a company with one is refused. The proposal shows each founder’s shares and percentage of the fully diluted total. A person with the ADMIN role confirms it in the web app; nothing is written until then, and everything is dated the company’s incorporation date. Managing your cap table |
POST /api/v1/preview_buyback_batch | model | EDITOR | Preview a buy-back from one or more sellers without recording anything: for each line, the lot (security id), its holder, the shares and the price per share. Returns outstanding shares before and after, each holder’s shares and ownership before and after, the total paid, any invalid lines in plain words, and a warning when the purchase is large enough for the QSBS redemption rule (IRC §1202(c)(3)). Repurchased shares go to treasury until the board retires them. Record it with record_buyback_batch. Share buy-backs |
POST /api/v1/record_buyback_batch | write:propose | ADMIN | Propose recording a buy-back from one or more sellers as one event: a name, an effective date, an optional note, and a line per lot (security id, holder, shares, price per share). The proposal shows every holder’s outstanding shares and ownership before and after, the shares moving to treasury and the total paid; it is blocked on any invalid line, and warns on a future date, a signature request still out on a lot, and the QSBS redemption rule. Confirming writes one REPURCHASE_SHARES ledger transaction per line, all or nothing, and the batch record the board consent and the sellers’ agreements are sent from. An ADMIN confirms. Share buy-backs |
POST /api/v1/list_buyback_batches | read | VIEWER | List the buy-backs recorded as one event with several sellers (the Buy-backs page): each one’s name, date, note and total paid; each seller’s repurchase transaction, shares, price and amount; whether the board consent and each seller’s repurchase agreement are not sent, out for signature or signed; and whether the board approval is still a draft (it is approved only when every director has signed). Newest first. Single-lot buy-backs recorded with record_buyback are on the ledger (list_securities), not here. Share buy-backs |
POST /api/v1/record_safe | write:propose | EDITOR | Record a signed SAFE for a stakeholder: the investment amount, valuation cap, discount, post- or pre-money form, MFN and pro-rata terms and the issue date, as an outstanding convertible instrument numbered for matching to the signed document. Nothing is issued on the cap table until the SAFE converts in a priced round (close_priced_round). Money is dollars as strings; a SAFE with an MFN provision is recorded but conversion modeling refuses it. Proposed for a person to confirm. SAFEs & convertibles |
POST /api/v1/close_priced_round | write:propose | ADMIN | Record a priced round on the cap table as one legal event: authorize a new preferred class (or issue into an existing one), issue it to each new-money investor at the round price (pre-money valuation over pre-money fully-diluted shares), convert each selected SAFE or convertible note at the better of its cap price and discounted round price, and optionally enlarge an option pool to a target fraction of post-money fully diluted. Proposed for an admin to confirm; the proposal reports every conversion and the pro-forma ownership before and after. Money is dollars as strings; a convertible with an MFN provision blocks the close. Model it first with model_priced_round. Recording a priced round |
POST /api/v1/record_convertible_note | write:propose | EDITOR | Record a signed convertible note for a stakeholder: the principal, annual interest rate and day-count basis (ACT/365, ACT/360 or 30/360), valuation cap, discount, maturity date and the issue date, the change-of-control repayment multiple (the greater of that multiple of principal plus interest and conversion at the cap, on a sale before conversion), and whether the cap is post-money (postMoney; omit when the note does not say, and pre-money is assumed), as an outstanding convertible instrument numbered for matching to the signed document. Nothing is issued on the cap table until the note converts in a priced round (close_priced_round), which accrues its interest to the close date. Money is dollars as strings. Proposed for a person to confirm. SAFEs & convertibles |
POST /api/v1/edit_convertible_note | write:propose | EDITOR | Propose correcting an outstanding convertible note’s terms: its change-of-control repayment multiple (on a sale before conversion the holder takes the greater of that multiple of principal plus interest and converting at the cap), valuation cap, whether the cap is post-money or pre-money, whether its fully diluted count includes the round's option-pool increase, discount, interest rate or maturity date. Principal, holder and issue date cannot be edited (cancel and record it again). With applyTo "issue" the same change is made to every outstanding note of the same note issue (identical terms) in one change. The proposal shows each field before and after and whose notes it touches; the old terms stay in the change log. SAFEs & convertibles |
POST /api/v1/edit_safe | write:propose | EDITOR | Propose correcting an outstanding SAFE’s terms: its valuation cap, discount, whether it is the post-money or pre-money form, and its MFN and pro rata rights. Investment, holder and date cannot be edited (cancel and record it again). With applyTo "terms" the same change is made to every outstanding SAFE with identical terms. The proposal shows each field before and after; the old terms stay in the change log. SAFEs & convertibles |
Stakeholders
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/delete_stakeholder | write:propose | EDITOR | Propose deleting a stakeholder record that nothing refers to, such as one added by mistake. It is blocked when the stakeholder is on the ledger (shares issued, transferred, repurchased or cancelled), has any grant or instrument, an 83(b), ISO-sale or Form 3921 record, a signature request, portal access or an open invite, records merged into it, documents filed on it, or fund records. A duplicate that holds anything should be merged (merge_stakeholders) instead. The proposal shows what is removed. Deleting cannot be undone; a person with the EDITOR role confirms it in the web app. Importing stakeholder emails |
POST /api/v1/merge_stakeholders | write:propose | ADMIN | Propose merging a duplicate stakeholder (mergedId) into the record that stays (survivorId), for the same person or entity entered twice. The duplicate’s shares are shown under the survivor from then on, and its grants, instruments and documents are listed on the survivor’s page; the ledger is not rewritten. The proposal shows both holders’ shares and percentages before and after, every holding that moves, and warns when the two records differ in type or e-mail or the duplicate has portal access. There is no undo for a merge in the app. A person with the ADMIN role confirms it. Importing stakeholder emails |
POST /api/v1/create_stakeholder | write:propose | EDITOR | Add a stakeholder (an individual, entity or trust) to the company with a legal name and, optionally, an email, mailing address, notes, relationship to the company (founder, employee, advisor, investor) and employment status. A founder or employee with no status sent is recorded as EMPLOYEE, an advisor as ADVISOR. Creates no security; issue shares or grant options to the new holder afterwards. A name and type already on the cap table is refused. Tax ids and bank details cannot be set here. Importing stakeholder emails |
POST /api/v1/update_contact | write:propose | EDITOR | Update a stakeholder's contact details: legal name, email, mailing address or notes; their employment status (EMPLOYEE, CONTRACTOR, ADVISOR, DIRECTOR or OTHER) and the date it took effect; their relationship to the company (FOUNDER, EMPLOYEE, ADVISOR, INVESTOR or OTHER); and optionally record or clear their departure date and post-termination exercise window. Only the fields sent change; an email, address, status or relationship of null clears it. Tax ids and bank details cannot be changed here. Importing stakeholder emails |
POST /api/v1/bulk_import_contacts | write:propose | EDITOR | Backfill stakeholder emails, departure dates and relationship labels from a contact sheet: JSON rows, or a CSV/XLSX export as base64 up to 8 MB. Rows are matched to existing stakeholders by email and name; only confident matches are applied, an existing different email is kept unless overwrite is set, and the result reports every row as matched, unmatched, changed or needing review. Creates no stakeholders and writes no ledger entry. Importing stakeholder emails |
POST /api/v1/set_termination | write:propose | EDITOR | Record that a stakeholder departed on a date, with an optional post-termination option exercise window in days, or reinstate them by sending null. Vesting on every grant they hold stops at that date and the unvested remainder returns to the pool; no ledger entry is written and nothing is cancelled. Importing stakeholder emails |
POST /api/v1/revoke_portal_access | write:propose | EDITOR | Propose revoking a stakeholder's holder-portal access: every login linked to them loses the read-only view of their own equity in this company, and any invite they have not accepted yet is cancelled. Their holdings, documents and records are unchanged, nobody is e-mailed, and a new invite restores access. A person with the EDITOR role confirms it in the web app. Stakeholder portal |
Governance
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/draft_board_consent | write:propose | ADMIN | Propose a board approval to record: the resolution title, what it authorizes (a grant, a pool, an issuance, a SAFE or note, a 409A, a financing, a repurchase), whether the board met or consented in writing, the date, notes and the record ids it covers. An ADMIN confirms it in the web app; the confirmation records it and answers with the authenticated link to the consent PDF. Nothing is sent to anyone. Board approvals |
POST /api/v1/request_signature | write:propose | EDITOR | Propose sending a document for e-signature: a grant notice, SAFE, RSPA or repurchase agreement (the holder signs), a board consent (name the directors; ADMIN only) or a document already attached to a record (name the signers). The EDITOR who confirms in the web app sends it: the request is anchored to the PDF’s sha256 and each signer is mailed a single-use signing link. Warns when a request for the same document is already out. Documents & e-signature |
POST /api/v1/send_stockholder_consent | write:propose | EDITOR | Propose a written stockholder consent: a title, the resolution text and optionally the share classes whose holders should sign. The EDITOR who confirms in the web app sends it: the consent is recorded, a signature request with one signer per holder is anchored to the consent PDF, and each holder with an email is mailed a single-use signing link. Documents & e-signature |
POST /api/v1/set_requisite_holders_threshold | write:propose | ADMIN | Propose setting (or clearing, with null) the stored Requisite Holders threshold for one financing: a percentage and/or free text, e.g. "66.666667" and/or "a majority of Series A voting as a class". No charter is parsed; this records what the charter is understood to require, as a plain default for the Voting page’s majority calculator and consent send form, always overridable for a given run. Both fields are required (send the current value to leave one unchanged, or null to clear it). A person with the ADMIN role confirms it. Voting |
POST /api/v1/record_409a | write:propose | ADMIN | Record a valuation of record from its figures: fair market value per share (a decimal string), the effective date, how it was determined (a §409A appraisal, a board determination or another method), the provider and an optional expiry. Checks the value against the range the company’s own valuation history implies and discloses any valuation already on file for the same date, which must be resolved with onSameEffectiveDate (REPLACE voids it, KEEP_BOTH keeps it). An exact copy of one on file (same date, method and value) is refused; only REPLACE gets past it. The new record prices option strikes from its effective date. To attach the report PDF, first send it to ingest_409a_report and pass the uploadId it returns as sourceUploadId. A person with the ADMIN role confirms. Compliance & tax |
POST /api/v1/mark_83b_filed | write:propose | EDITOR | Record that an 83(b) election was filed with the IRS, dated the moment a person confirms. A filing after the 30-day window is recorded as filed late (an invalid election that stays flagged), never as a clean filing; the proposal warns when the window has already closed. Only proposed from here: a person with the EDITOR role performs the mark in the web app. Option Holdings |
POST /api/v1/mark_form3921_issued | write:propose | EDITOR | Record that Form 3921 (IRC §6039) was issued to the employee and filed with the IRS for one exercised ISO lot, by the lot’s security reference, its grant, its holder and the tax year of the exercise. Idempotent per lot. The proposal warns when the lot is not one still owed a form. Only proposed from here: a person with the EDITOR role performs the mark in the web app. Option Holdings |
POST /api/v1/mark_de_filed | write:propose | EDITOR | Record that a tax year’s Delaware annual report and franchise tax were filed and paid on the state portal, with the amount paid (cents, as a string) and the confirmation number. The year must already have a prepared filing in Tenacap; the proposal is blocked until it does. Only proposed from here: a person with the EDITOR role performs the mark in the web app. Delaware franchise tax |
POST /api/v1/mark_bvi_register_filed | write:propose | EDITOR | BVI companies only: record that the updated register of members was filed with the Registrar through the registered agent (BVI Business Companies Act s.43A requires it within 30 days of any change), dated the day it was filed. The mark covers every change to the register dated on or before that day; the next change opens a new 30-day deadline. Only proposed from here: a person with the EDITOR role performs the mark in the web app. BVI companies |
POST /api/v1/set_de_reminder | write:propose | EDITOR | Turn the Delaware franchise-tax reminder on or off and set how many days before the March 1 deadline it starts. When on, Tenacap e-mails the authorized filers the prepared filing package each year until that year is marked filed. Only proposed from here: a person with the EDITOR role applies it in the web app. Delaware franchise tax |
POST /api/v1/correct_409a | write:propose | ADMIN | Correct a recorded valuation in place when it was entered wrong: its fair market value per share (a decimal string), its effective date or its method (a §409A appraisal, a board determination or another method). Give the valuation id and only the fields that change. Refuses a correction that would make it an exact copy of another valuation on file (same date, method and value). Warns when the new date already has a valuation or the new value is far outside the company’s own history. To withdraw a valuation instead, use void_409a. A person with the ADMIN role confirms. Compliance & tax |
POST /api/v1/void_409a | write:propose | ADMIN | Void a recorded valuation that was entered in error. It stays in the valuation history marked VOID, but stops counting as the valuation in force, so it no longer prices option strikes; the next valuation in line (if any) takes over. Nothing is deleted. Give an optional reason (for example "duplicate of <valuation id>"); it is kept in the audit trail and shown in the valuation history. To fix a figure instead, use correct_409a. A person with the ADMIN role confirms. Compliance & tax |
POST /api/v1/ingest_409a_report | model | ADMIN | Read a 409A report PDF (base64, up to 3 MB) and return a draft valuation: fair market value per share, effective date, expiry, provider, the provider’s reference and the method, each with how confident the reading is and the text it came from, plus a warning when the value is far outside the company’s own valuation history. Records nothing on the company: check the draft against the report, then propose record_409a with the figures and the returned uploadId as sourceUploadId, which attaches the PDF to the valuation. Needs the ADMIN role. Compliance & tax |
POST /api/v1/order_409a | write:propose | ADMIN | Order an independent 409A appraisal from Tenacap’s valuation partner, 409.AI, a firm outside Tenacap. It sends the company’s cap table and overview to 409.AI and opens a paid order the founder pays 409.AI for directly, so it is only proposed from here: a person with the ADMIN role places it by confirming in the web app. Takes the valuation date, the contact e-mail (default: the confirming admin’s; it becomes their 409.AI account), the company website, who is requesting it and a short company overview. Afterwards the founder pays and finishes 409.AI’s questionnaire from the 409A page. Refused for an LLC and while another order is in progress. Compliance & tax |
POST /api/v1/resubmit_409a_order | write:propose | ADMIN | Amend an open 409A order before it is submitted on 409.AI, or finish a send that failed part-way: an amended company overview and website with the cap table as it stands. The valuation date and contact stay as ordered. It sends the cap table to 409.AI, a firm outside Tenacap, so it is only proposed from here and a person with the ADMIN role sends it by confirming. Financial spreadsheets are attached on the 409A page, not from here. Refused once the order is submitted to the appraiser or complete. Compliance & tax |
POST /api/v1/confirm_409a_order | write:propose | ADMIN | Record the 409A report the valuation partner delivered for an order as the company’s valuation of record: the fair market value per share, effective date and expiry, checked against the report. The record is a §409A appraisal from 409.AI with the report attached, and the order is closed. Blocked until the report has arrived; discloses any valuation already on file for the same date, resolved with onSameEffectiveDate as for record_409a (an exact copy of one on file is refused unless REPLACE); warns when the value differs from what Tenacap read in the report. A person with the ADMIN role confirms. Compliance & tax |
POST /api/v1/record_83b_election | write:propose | EDITOR | Start tracking an 83(b) election for restricted stock or an early-exercised option grant already on the cap table, from the purchase or exercise date that starts the 30-day filing clock. The deadline is day 30, moved to the next business day when it falls on a weekend or DC holiday, and the result says whether it has already passed. Refused when the security is not restricted stock or an early-exercised grant held by that holder in this company. Use mark_83b_filed once it is filed. Option Holdings |
POST /api/v1/link_83b_security | write:propose | EDITOR | Link an existing 83(b) election to the restricted stock or early-exercised option grant it covers, so it counts in the option-holdings roll-up that flags a missed filing window. For elections recorded before the security picker existed, whose security is free text. Refused unless the security is restricted stock or an early-exercised grant held by the election's own filer in this company. The result restates the 30-day filing deadline and whether it has passed. Option Holdings |
POST /api/v1/set_83b_status | write:propose | EDITOR | Set an 83(b) election to not filed, late (the 30-day window was missed) or not applicable, clearing any recorded filed date. To record a filing use mark_83b_filed, which dates it and keeps a filing after the window flagged as late. The proposal warns when the change contradicts the deadline, and the result states the deadline and whether it has passed. Only proposed from here: a person with the EDITOR role confirms it in the web app. Option Holdings |
POST /api/v1/set_rule_701_total_assets | write:propose | ADMIN | Propose setting (or clearing, with null) the company’s total assets, in cents, which the Rule 701 cap is computed from: the greatest of $1,000,000, 15% of total assets and 15% of the class outstanding over any twelve months (17 CFR §230.701(d)(2)). Use the most recent balance sheet, no older than the last fiscal year end. The proposal shows the cap and headroom before and after, and the Delaware franchise tax when the filing has no gross assets of its own and uses this figure. A person with the ADMIN role confirms it. Compliance & tax |
POST /api/v1/record_qsbs_attestation | write:propose | ADMIN | Draft the company’s QSBS active-business answer for a tax year: yes when at least 80% of its assets by value were used in the active conduct of a qualified trade or business (IRC §1202(c)(2), (e)(1)), which excludes fields such as health, law, engineering, accounting, consulting, financial services, banking, investing, farming and hotels and restaurants (§1202(e)(3)). The QSBS analysis needs a yes for every year a holding is held. Only proposed from here: it is a statement in the company’s name, so a person with the ADMIN role makes it by confirming, and is recorded as the one who attested. QSBS (§1202) |
POST /api/v1/record_qsbs_gross_assets | write:propose | ADMIN | Propose recording the company’s aggregate gross assets (cents) on a date, which the QSBS asset test reads: stock is QSBS only if gross assets never exceeded $50,000,000 before and immediately after an issuance on or before July 4, 2025, or $75,000,000 for one after (IRC §1202(d)(1)). The proposal says whether the figure is under, near or over the ceiling for stock issued that day, and warns which later issuances a figure over it fails. A person with the ADMIN role confirms it. QSBS (§1202) |
POST /api/v1/record_asc718_assumptions | write:propose | ADMIN | Propose an ASC 718 assumption set: expected volatility, risk-free rate, expected term and dividend yield (decimal strings, fractions), in effect from a date. The ASC 718 report values every option granted on or after that date with them (Black-Scholes) until a later set takes over, never a grant another set already measures, since ASC 718 measures an award once, at its grant date. The proposal shows the grant-date fair value and the expense to date before and after. Corrections are a new set, never an edit. A person with the ADMIN role confirms it. ASC 718 stock-comp report |
POST /api/v1/save_de_filing_profile | write:propose | EDITOR | Propose saving the Delaware annual-report details: file number, registered agent, principal office, phone, officers, directors, the authorizing party, and total gross assets (cents; the Form 1120 Schedule L total assets the Assumed Par Value Capital method divides by issued shares). A field left out keeps its value. When gross assets change, the proposal shows the franchise-tax estimate before and after. A person with the EDITOR role confirms it. Delaware franchise tax |
POST /api/v1/prepare_de_filing | write:propose | EDITOR | Propose saving a tax year’s Delaware franchise-tax figures as the prepared filing: the Authorized Shares and Assumed Par Value Capital methods, the lesser of the two, the $50 annual-report fee and the total due (or an LLC’s flat annual tax). The same figures as get_de_franchise_tax and the Delaware filings page, recomputed when the proposal is confirmed. A year must be prepared before mark_de_filed can mark it filed. A person with the EDITOR role confirms it. Delaware franchise tax |
POST /api/v1/send_portal_invite | write:propose | EDITOR | Propose inviting one stakeholder to the holder portal, where they see only their own equity in this company. Confirming sends one e-mail to the address on file for that stakeholder, with a single-use link that expires in 14 days; accepting it needs a login with that same address. Only proposed from here: a person with the EDITOR role confirms it in the web app, and the e-mail goes out then, under their name. Stakeholder portal |
POST /api/v1/set_board_approval_status | write:propose | ADMIN | Propose marking a recorded board approval APPROVED, once the board has acted, or back to DRAFT. The proposal names the approval and its status before and after, and warns when a written consent is marked approved while its signature request is still out or was declined (a Delaware board acts by written consent only when every director consents). A treasury retirement’s approval cannot change status. An ADMIN confirms it in the web app, and is recorded as the person who attested it. Nothing is sent to anyone. Board approvals |
POST /api/v1/add_board_member | write:propose | ADMIN | Propose adding a director to the voting-board roster, by name and e-mail with an optional title. The roster is who a board consent’s signer list starts from; a director need not hold equity. Nobody is e-mailed. An ADMIN confirms it in the web app. Board approvals |
POST /api/v1/update_board_member | write:propose | ADMIN | Propose editing a director on the voting-board roster: their name, e-mail or title, or marking them inactive (kept on the record, no longer offered as a consent signer) or active again. The proposal shows each field before and after. Nobody is e-mailed. An ADMIN confirms it in the web app. Board approvals |
POST /api/v1/remove_board_member | write:propose | ADMIN | Propose removing a director from the voting-board roster. Recorded approvals and signature requests already sent are unchanged, and the change log keeps the name; to keep a director on the record without offering them as a signer, update_board_member can mark them inactive instead. Nobody is e-mailed. An ADMIN confirms it in the web app. Board approvals |
POST /api/v1/send_stockholder_email | write:propose | EDITOR | Propose an e-mail to the company’s stockholders: a subject, a plain-text message and optionally a button link, to every stakeholder with an e-mail on file or only the stockholders of record of named share classes (issued shares; option and RSU holders are not included). The proposal lists every recipient by name and address and shows the message as it will go out, and names every holder it cannot reach for want of an e-mail address; nothing is sent until a person with the EDITOR role confirms it in the web app, under their name. A confirm sends nothing if the recipient list has changed since the proposal. Importing stakeholder emails |
POST /api/v1/send_buyback_board_consent | write:propose | ADMIN | Propose sending the board consent that approves a recorded buy-back to the directors for e-signature (name each director and their e-mail). The first send records the buy-back’s board approval as a draft; it becomes approved, dated with the last signature, when every director has signed (DGCL §141(f)), and stays a draft if one declines. A later send re-sends against the same approval. The proposal names the buy-back, the approval and every director. Nothing is sent until an ADMIN confirms in the web app; the confirmer sends it, and each director is mailed a single-use signing link. Warns when a consent is already out or signed, and when an active director on the board roster is not among the signers. Share buy-backs |
Data
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/attach_document | write:propose | EDITOR | Propose attaching a file (a PDF, an image or a Word document, base64 up to 3 MB) to a record: a grant or other instrument, a share holding (SECURITY), a board approval, an option plan or a stakeholder. Say what it is (board consent, grant agreement, stock certificate, plan document, 83(b) election or other) and optionally give it a title. The proposal names the record, the file and its SHA-256, and warns when the same file is already on the record. Confirming stores the file and the attachment; an EDITOR confirms. A larger file is attached in the web app. Documents & e-signature |
POST /api/v1/request_document_upload | model | EDITOR | Attach a batch of documents the user gave you (a folder of stock option agreements, or a whole mixed folder: grant agreements, 83(b) elections, signed SAFEs and convertible notes, board consents, stock certificates) to the right records, without sending the files through this tool. Use it after an import or company setup when the user offers their documents. Steps: (1) read each file and say what it is in documentType; (2) find each grant agreement’s grant with list_grants by what is printed in it: holder name, share count, grant date, exercise price and the vendor grant id (sourceGrantId, e.g. Pulley "ES-12"); a board consent’s approval with get_board; a certificate’s holding with list_securities; (3) call this tool ONCE with the whole plan: every file with its filename, its sha256 if you can compute it, documentType, and, when you found its record, linkedType and linkedId (INSTRUMENT and the grant id for a grant agreement) and a one-line reason naming what matched. 83(b) elections, SAFEs and notes need no record from you: give documentType and Tenacap matches them itself from the text (the taxpayer, shares and transfer date; the investor, amount and date) and flags a SAFE or note whose printed cap, discount or interest differs from the cap table. Never guess: a file you are not sure of goes in the plan with no linkedType or linkedId, and the person chooses on the page. Documents Tenacap does not file yet (stock purchase agreements, stock powers, exercise notices, the charter) go in as documentType OTHER. (4) If you have code execution with network access, upload each file’s bytes to its uploadUrl with HTTP PUT (raw body) from your sandbox (for example from /mnt/user-data/uploads/); otherwise give the user uploadPageUrl and ask them to drop the same files there. Either way nothing is attached until a person with the EDITOR role presses Confirm on that page, so tell them to. Files are PDFs, images or Word documents up to 4 MB each; links last 24 hours. Use attach_document instead for a single small file you can send as base64. Documents & e-signature |
POST /api/v1/add_document_upload_file | model | EDITOR | Add one file (base64, up to 3 MB) to an upload session request_document_upload opened. It is matched to the plan by sha256, then by filename; a file the plan does not cover is matched by Tenacap from the text printed in it, or left for the person to place. Nothing is attached until a person confirms on the session page. Prefer the per-file uploadUrl from request_document_upload, which takes the raw bytes and has no base64 overhead. Documents & e-signature |
POST /api/v1/confirm_document_upload | write:propose | EDITOR | Propose attaching files of an upload session (request_document_upload) to their records: each file in fileIds (at most 25, each already received) goes on the record in choices, else the one in the plan, else the one Tenacap matched from its text; a file with no record is left. A person confirms in the web app; usually they press Confirm on the session page instead, so call this only when the user asks you to. Documents & e-signature |
POST /api/v1/read_document_terms | model | EDITOR | Read the exit terms printed in a file of an upload session: from a convertible note, the change-of-control repayment multiple, whether the holder gets the greater of repayment or conversion, the cap and whether it is pre-money or post-money (a note with a cap that does not say which comes back as an information line, not_stated, with nothing to confirm), and the discount and interest; from a certificate of incorporation or designations, each preferred class’s liquidation multiple, participation, participation cap and seniority. Each term comes with the sentence and page it is printed on, beside the record’s value. Changes no record: confirm_document_term writes a term once an ADMIN confirms. Documents & e-signature |
POST /api/v1/confirm_document_term | write:propose | ADMIN | Propose writing one exit term read from an uploaded note or charter (read_document_terms) onto its record: a convertible note’s change-of-control multiple, cap, cap basis (pre-money or post-money, written as the note’s postMoney), discount or interest, or a preferred class’s liquidation multiple, participation, participation cap or seniority. Pass the termId and the documentValue read_document_terms returned; the value written is the one printed in the document, never one you supply. The record defaults to the file’s note or the class the charter names (recordId to choose another). Seniority writes the charter’s whole order of payment. It records which document and sentence the term came from, so the exit model can show it as confirmed rather than assumed. A person with the ADMIN role confirms it. Documents & e-signature |
POST /api/v1/start_document_import | model | EDITOR | Open a page where the user drops a folder of the company’s signed documents and Tenacap files each one itself: it reads what each PDF is (grant agreement, 83(b) election, SAFE, convertible note, board consent, stock certificate) and matches it to its record by what is printed in it, flagging a SAFE or note whose printed cap, discount or interest differs from the cap table. Files it cannot place get a picker. Nothing is attached until a person with the EDITOR role presses Confirm on that page. Give the user uploadPageUrl. Use this when you cannot read the files yourself; when you can, use request_document_upload, which carries your own match and reason for each file. The link lasts 24 hours. Documents & e-signature |
POST /api/v1/detach_document | write:propose | EDITOR | Propose taking an attached document off its record. The proposal names what goes: the document’s title, kind, file and SHA-256, the record it leaves, and when it was attached. The document stops being listed on the record and in the holder’s portal; the file itself and the audit history are kept. Warns when a signature request on the same file is still out (detaching does not withdraw it). An EDITOR confirms. Documents & e-signature |
POST /api/v1/import_certificate | write:propose | EDITOR | Propose filing one stock certificate PDF (base64, up to 3 MB) against the holding whose certificate number is printed in it. The proposal names the holding (holder, class, shares, certificate number) and the file. It is blocked when the PDF has no readable text, when no holding here has a number found in it, when it names more than one holding (the candidates are listed: attach it to one with attach_document, linkedType SECURITY), or when the same file is already on that holding. Send one file per call. An EDITOR confirms. Documents & e-signature |
POST /api/v1/export_open_schema | read | VIEWER | The company’s complete cap table in Tenacap’s open schema (v1 CapTableBundle: company, share classes, stakeholders, holdings, instruments, vesting schedules, the ledger and the audit log). `json` returns the bundle inline; `csv` (outstanding holdings) and `zip` (bundle plus holdings and stakeholders sheets with a checksum manifest) return an authenticated download link. Never includes tax ids, bank details or addresses, whatever the caller’s role. Export & open schema |
POST /api/v1/generate_diligence_pack | read | EDITOR | A download link for the company’s diligence pack: one zip with the open-schema cap table (cap-table.json, holdings.csv, stakeholders.csv), the Form 3921 and ASC 718 reports, the 409A valuation history, a hash-chained ledger audit excerpt and a checksum manifest. The link is authenticated with the same credential and never includes tax ids, bank details or addresses, whatever the caller’s role. Diligence pack |
POST /api/v1/export_ocf | read | VIEWER | The company’s cap table as a standards-compliant Open Cap Format (OCF) v1.2.0 bundle: Manifest.ocf.json plus the issuer, stakeholders, stock classes, stock plans, vesting terms, valuations and transaction objects, each validated against the published OCF JSON schemas. A different format from export_open_schema (Tenacap’s own open schema): this is the Open Cap Table Coalition’s external standard, for moving a cap table to another OCF-reading tool. Never includes tax ids, bank details or addresses. Rows Tenacap tracks that OCF has no object for (phantom/SAR awards, treasury-retired shares) are named in the bundle’s manifest comments, not silently dropped. Export & open schema |
POST /api/v1/import_cap_table | write:propose | ADMIN | Import a Carta, Pulley, Mantle or Tenacap cap-table export into an empty company. Attach the file as file_base64 (up to 3 MB) or omit it to receive a one-time browser upload link, which is the only link to give the person: after the upload the same page takes them on to review and confirm. The proposal is the import preview: the totals cross-check, the rows that will be skipped and the parser’s findings, with the ownership picture the company would have. Append only: a company that already has a cap table is refused, because replacing one deletes ledger rows and is not available to an assistant. An ADMIN confirms. Importing your cap table |
POST /api/v1/create_company_from_import | write:propose | ADMIN | Create a company from a Carta, Pulley, Mantle or Tenacap cap-table export, in a workspace that has none yet. State the company’s legal name, incorporation date, jurisdiction and entity type. A cap-table export does not carry them, so ask or read them off the charter. Attach the file as file_base64 (up to 3 MB) or omit it to receive a one-time browser upload link, which is the only link to give the person: after the upload the same page takes them on to review and confirm. The proposal is the import preview: the totals cross-check, the rows that will be skipped, the parser’s findings and the ownership picture the company would have. Confirming it is what creates the company, and an ADMIN of the workspace confirms. Call list_companies first for the workspace_id; if the workspace already holds a company, use import_cap_table with its company_id. Once the company exists, offer to file its signed documents (see nextSteps): request_document_upload, or start_document_import. Importing your cap table |
POST /api/v1/create_company | write:propose | ADMIN | Create a company with no cap table yet, in a workspace that has none, for a founder with no Carta, Pulley or Mantle export to import (with an export, use create_company_from_import instead). State the company’s exact legal name, incorporation date, jurisdiction and entity type: ask, or read them off the charter. An ADMIN of the workspace confirms, and confirming is what creates the company. Then fill it in with the ordinary tools and the returned company_id: add_share_class for the authorized shares, create_stakeholder and issue_founder_stock for each founder, record_safe, create_option_pool. Once it is filled in, offer to file the company’s signed documents: request_document_upload, or start_document_import when you cannot read the files. Call list_companies first for the workspace_id. Connect your AI assistant |
POST /api/v1/list_import_findings | read | VIEWER | The findings an import raised that still need a person’s eye: holdings the source stated that are not on the cap table, totals that disagree with the file, vendor data warnings and fields the file stated that were not placed. Each says who owns the fix (you can fix, ours to fix, yours to check) and its status. Defaults to the unfinished ones (OPEN and ACKNOWLEDGED). Importing your cap table |
POST /api/v1/get_import_checks | read | VIEWER | The import checks for this company: after an import is saved, Tenacap reads the uploaded file a second time and checks every holder and certificate on the saved cap table against it (shares by class, every certificate present, totals, $0 and reissued-certificate prices). Returns each check with Passed, Needs a look or Not checked, what it covered, and the holders behind any that need a look. Defaults to the newest run; pass importSessionId for one import. Importing your cap table |
POST /api/v1/acknowledge_import_finding | write:propose | EDITOR | Mark an OPEN import finding as seen and left for now. It stays on the review list and in the carry-forward count: acknowledging is not resolving, and a finding about a wrong number is never dismissed. Proposes the change for an EDITOR to confirm. Importing your cap table |
POST /api/v1/upload_import_file | model | EDITOR | Upload a Carta, Pulley, Mantle or Tenacap cap-table export (base64, up to 3 MB) into a workspace and open an import session, the first step of the import wizard. Nothing reaches the cap table: next call parse_import with the returned import_session_id, then propose commit_import, which a person confirms. For one step instead of three, use import_cap_table (a company with no cap table yet) or create_company_from_import (a workspace with no company), which also hand out a browser upload link for a larger file. Needs the EDITOR role in the workspace; call list_companies for the workspace_id. Importing your cap table |
POST /api/v1/parse_import | model | EDITOR | Read an uploaded cap-table export (the import_session_id from upload_import_file) with the parser for its vendor: the second step of the import wizard. Returns how many stakeholders, share classes, ledger transactions and skipped rows it found; nothing reaches the cap table until commit_import is proposed and confirmed, and that proposal shows the full preview and the totals cross-check. Carta and Pulley exports do not carry the company’s incorporation date, jurisdiction or entity type: pass them as company, or omit it when the workspace already has a company to use its identity. Needs the EDITOR role in the workspace. Importing your cap table |
POST /api/v1/commit_import | write:propose | EDITOR | Write an uploaded and parsed cap-table import (the import_session_id from upload_import_file and parse_import, or one the person uploaded in the app) to the cap table: the last step of the import wizard. The proposal is the import preview: the totals cross-check, the rows that will be skipped, the parser’s findings and the ownership picture. Into a company with no cap table yet it appends; in a workspace with no company it creates one from the file. A company that already has a cap table is refused, because replacing one deletes ledger rows and is not available to an assistant; and when the file’s own totals disagree with its rows, the person decides on the import page. An EDITOR or ADMIN of the workspace confirms. Once it is committed, offer to file the company’s signed documents (see nextSteps): request_document_upload, or start_document_import. Importing your cap table |
POST /api/v1/cancel_import | write:propose | EDITOR | Cancel an import that has not been committed yet, and delete the file that was uploaded for it. Nothing on the cap table changes. A committed import cannot be cancelled: to delete its file, use delete_import_file. Proposes the cancel for an EDITOR of the workspace to confirm. Importing your cap table |
POST /api/v1/delete_import_file | write:propose | EDITOR | Delete the file that was uploaded for a committed import, as the founder may ask at any time: Tenacap keeps it for the life of the account otherwise. Only the file goes; the cap table, the import’s record and the audit trail stay, and the deletion is itself recorded. An import that has not been committed is cancelled with cancel_import instead, which deletes its file too. Proposes the deletion for an EDITOR of the workspace to confirm. Importing your cap table |
POST /api/v1/resolve_import_finding | write:propose | EDITOR | Mark an import finding resolved, with a short resolution saying what settled it, which takes it off the review list and out of the carry-forward count. Use it when the finding no longer holds (the founder confirms the cap table is complete, or a corrected export fixed it); to leave a finding for later without closing it, use acknowledge_import_finding. Proposes the change for an EDITOR to confirm. Importing your cap table |
POST /api/v1/request_import_finding_review | write:propose | VIEWER | Ask the Tenacap team to look at an import finding the founder cannot settle themselves: a figure the file states that Tenacap’s disagrees with, or one marked ours to fix. Confirming files an urgent issue with the team carrying the finding, both figures and the import, and the team replies to the person who confirms, at their e-mail. Confirm-only: this proposes the ask, and it is sent only when a person in the company confirms it in the web app. Other findings have their own fix (list_import_findings says whose it is). Importing your cap table |
POST /api/v1/send_feedback | write:propose | EMPLOYEE | Send a bug report, a suggestion or a question to the Tenacap team. It files an issue with the engineering team carrying the message, the user’s account e-mail (so the team can reply), the workspace and company, and which assistant sent it. Only call this when the user has asked to send feedback or has said yes when you offered: show them the exact text first and send it as they approved it; never send on your own initiative. It runs at once, not as a proposal, and changes nothing in Tenacap: no cap-table record, no e-mail to anyone. Text only, no screenshots: to attach one, the user can use the Provide feedback button in the Tenacap web app. kind is bug, suggestion or question; pass company_id when the note is about one company, and context for what the user was doing or which tool misbehaved. Up to 10 notes an hour per user. Connect your AI assistant |
Admin
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/admin_list_users | read | ADMIN | Superadmin only. One page of every account on the platform, newest signup first: email, name, verification, last sign-in, lock state, and the workspaces each one belongs to. Filter by member vs. portal-only, active vs. dormant, verified, and whether they are affiliated with a company. Use admin_get_user for one account’s full detail. Trust & security |
POST /api/v1/admin_get_user | read | ADMIN | Superadmin only. Full detail for one account: every workspace membership and the companies in it, linked sign-in providers, API tokens (with their scopes and revocation state), and recent audit activity this account authored. Trust & security |
POST /api/v1/admin_create_account | write:propose | ADMIN | Superadmin only. Propose creating a Tenacap account: an advisor (no workspace) or a founder (a new workspace, with this person as its ADMIN). The admin never sets or sees a password. Confirming sends a "set a password" e-mail and the account can sign in without the shared early-access password. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_update_account | write:propose | ADMIN | Superadmin only. One of: change an account's display name, or grant it a membership in a workspace the acting superadmin does not belong to (the one deliberate tenancy-crossing action here; it requires a reason, and notifies that workspace's admins). Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_resend_signin_link | write:propose | ADMIN | Superadmin only. Propose (re)sending an account its sign-in e-mail. Always mints a fresh link (any unused prior one stops working); the wording ("set a password" or "reset your password") is inferred from the account's own state, never chosen by the caller. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_force_password_reset | write:propose | ADMIN | Superadmin only. Propose forcing a password reset for an account that already has one. The mint is the same as admin_resend_signin_link, worded as a reset. If the account turns out to have no password yet, the e-mail sent is the "set a password" one instead: the wording always matches the account's real state, never the tool name used to reach it. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_lock_account | write:propose | ADMIN | Superadmin only. Propose locking an account: it refuses sign-in, ends any live browser session within one request, and refuses the account's API/MCP tokens (401) without revoking them. Clearing the lock restores them. Use admin_revoke_token to revoke a token permanently. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_unlock_account | write:propose | ADMIN | Superadmin only. Propose restoring an account's ability to sign in and its unrevoked API/MCP tokens' ability to authenticate. Does not restore a token that was separately revoked. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_revoke_token | write:propose | ADMIN | Superadmin only. Propose revoking any account's API token, whichever workspace or company it belongs to. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_delete_account_soft | write:propose | ADMIN | Superadmin only. Propose soft-deleting an account: locks it, revokes every API token, and removes every workspace membership, keeping the User row and its audit history. `confirmation` must be the account's own e-mail address, as written. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_delete_account_hard | write:propose | ADMIN | Superadmin only. Propose permanently deleting an account: the soft-delete composition, then the User row itself. Refused while the account authored a ledger transaction or a signature request anywhere, ever, or initiated an import session in a workspace that would survive it. Soft-delete it instead. `confirmation` must be the account's own e-mail address, as written. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_grant_operator | write:propose | ADMIN | Superadmin only. Propose granting SUPERADMIN or BUG_TRIAGE operator access to an e-mail address, effective immediately on confirm with no redeploy. Refused as redundant for an address already on the env-floor allowlist. Confirmed only in /admin, by a superadmin's own session. Trust & security |
POST /api/v1/admin_revoke_operator | write:propose | ADMIN | Superadmin only. Propose revoking a DB-backed operator grant (SUPERADMIN or BUG_TRIAGE) by its id. Cannot touch the env-floor allowlist, which stays a Vercel env edit, on purpose. Confirmed only in /admin, by a superadmin's own session. Trust & security |
Holder (your own equity)
| Operation | Scope | Role | What it returns |
|---|---|---|---|
POST /api/v1/list_my_companies | holder:read | VIEWER | The companies you hold equity in through Tenacap’s holder portal, each with the name you hold it under. Each id is the company_id the other holder tools take (get_my_equity, get_my_vesting, estimate_my_exercise and the rest). Shows only your own holdings; it never lists another holder or a company you hold nothing in. Connect your AI assistant |
POST /api/v1/get_my_equity | holder:read | VIEWER | Your own equity in one company, as the holder portal shows it: your shares and their vesting, your option grants (vested, unvested, cost to exercise the vested ones, today’s pre-tax value and a tax note), RSUs, phantom stock and stock appreciation rights, SAFEs and notes, your 83(b) elections, the company’s current fair market value and how it was set, and the estimated value of your shares. Only your own holdings; never another holder’s or the full cap table. Informational only, not tax advice. Connect your AI assistant |
POST /api/v1/get_my_vesting | holder:read | VIEWER | How much of your own equity in one company has vested, as of today or a date you give: each option grant (vested and unexercised, unvested, exercised), each RSU, restricted shares on a vesting schedule, and phantom awards that vest. Only your own holdings. Exercises are counted as recorded today, so a past date shows what had vested by then. Connect your AI assistant |
POST /api/v1/estimate_my_exercise | holder:read | VIEWER | What it would cost to exercise one of your own option grants: the exact cash to pay (strike × options, to the cent), and, as an estimate at the company’s current fair market value, the spread (value minus cost) that is taxed when you exercise, with the valuation’s date and method. Defaults to your vested, unexercised options. States the tax mechanism for an ISO or NSO but computes no tax bill. Informational only, not tax advice. Connect your AI assistant |
POST /api/v1/list_my_83b_elections | holder:read | VIEWER | Your own 83(b) elections in one company: each one’s filing deadline, status, days left, and the postmark date you told the company, if any. Also lists your early-exercised grants with no election on record, so a 30-day deadline is not missed in silence. "Filed" is the company’s record; telling the company you mailed it is not the same thing. Connect your AI assistant |
POST /api/v1/list_my_exercise_requests | holder:read | VIEWER | The requests you have sent one company, from your holder portal, to record an exercise of your option grant: which grant, how many options, your note, when you asked, and whether it is pending, fulfilled or dismissed. Only your own requests. A request is not an exercise: the company records the exercise. Connect your AI assistant |
POST /api/v1/list_my_documents | holder:read | VIEWER | Your own documents in one company: signature requests where you are a signer, with their status, and the files the company attached to you, your grants or your certificates. Each comes with a link that opens in your signed-in browser; the files themselves are not returned. Only documents that concern you. Connect your AI assistant |
POST /api/v1/request_exercise | holder:request | VIEWER | Prepare a request to one company to record an exercise of your own option grant: how many options, and an optional note. Nothing is sent from here. You get a link to your holder portal, where you check the number and send it with one click; only then are the company’s admins e-mailed. A request is not an exercise: the company records the exercise once you have paid the exercise price. Connect your AI assistant |
POST /api/v1/attest_my_83b_mailed | holder:request | VIEWER | Prepare telling one company the postmark date you mailed your own 83(b) election on. Nothing is recorded from here. You get a link to your holder portal, where you check the date and confirm it with one click. It records that you told the company; it does not mark the election filed, which the company does. Connect your AI assistant |
The OpenAPI document
/api/openapi.json is an OpenAPI 3.1 document generated from the same registry: one operation per row above, the request and response schemas, the error shape, the bearer security scheme, and for each operation x-tenacap-mode, x-tenacap-role and a link back to its Help center article. It is public and needs no token to read; feed it to any OpenAPI-aware client.
