---
title: "Create Security"
method: POST
path: "/extensions/roboinvestor/{graph_id}/operations/create-security"
tags: ["RoboInvestor"]
---

# Create Security

`POST /extensions/roboinvestor/{graph_id}/operations/create-security`

## Request

- Base URL: `https://api.robosystems.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.robosystems.ai/extensions/roboinvestor/{graph_id}/operations/create-security`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Register a security (common stock, preferred stock, warrant, convertible note, etc.) owned by this graph's entity. Optionally cross-links to an issuing entity in another graph via `source_graph_id` for mutual-handshake attribution.

**Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

## Path parameters

- `graph_id` string, required

## Headers

- `Idempotency-Key` string, nullable

## Request body

- CreateSecurityRequest: CQRS body for `POST /operations/create-security`. Mints a new security as Master Data — referenced by positions, never created inline by portfolio operations. The `terms` blob carries instrument-specific shape (liquidation preference, strike price, vesting) used by future waterfall-distribution modeling.
  - `entity_id` string, nullable: ID of the issuing entity. Optional only if `source_graph_id` is set (pre-association before the entity is finalized).
  - `source_graph_id` string, nullable: Optional pre-association to a tenant company graph. Lets you mint securities for an entity that hasn't been promoted to a real `entity_id` yet.
  - `name` string, required: Display name for the security (e.g. `Common Stock Class A`, `Series A Preferred`). 1-200 characters.
  - `security_type` string, required: Instrument family. Open vocabulary — common values: `common_stock`, `preferred_stock`, `warrant`, `convertible_note`, `safe`, `option`, `llc_unit`, `lp_interest`, `restricted_stock_unit`.
  - `security_subtype` string, nullable: Free-text refinement of `security_type` (e.g. `class_a`, `series_a`, `series_seed`). No vocabulary enforcement.
  - `terms` object: Instrument-specific terms blob (JSONB). Shape depends on `security_type` — common keys include `liquidation_preference`, `strike_price_cents`, `discount_pct`, `valuation_cap_cents`, `maturity_date`, `vesting`. Used by future waterfall-distribution modeling; treat as authoritative storage for instrument mechanics.
  - `authorized_shares` integer, nullable: Total shares the issuer is authorized to issue for this class. `null` for instruments where shares aren't a meaningful unit (e.g. convertible notes pre-conversion).
  - `outstanding_shares` integer, nullable: Shares currently issued and outstanding. Should be ≤ `authorized_shares` when both are set.

## Response `200`

Successful Response

- OperationEnvelopeSecurityResponse
  - `operation` string, required: Kebab-case operation name
  - `operationId` string, required: op_-prefixed ULID for audit and SSE correlation
  - `status` 'completed' | 'pending' | 'failed', required: Operation lifecycle state
  - `result` SecurityResponse: Read projection for a single security.
    - `id` string, required: Security ID (`sec_*` ULID).
    - `entity_id` string, nullable: ID of the issuing entity, when set.
    - `entity_name` string, nullable: Cached display name of the issuing entity, denormalized for list rendering. May lag the entity row's current name briefly.
    - `source_graph_id` string, nullable: Tenant graph this security is pre-associated to, when the issuer entity hasn't been promoted yet.
    - `name` string, required: Display name of the security.
    - `security_type` string, required: Instrument family (e.g. `common_stock`, `preferred_stock`, `warrant`, `convertible_note`).
    - `security_subtype` string, nullable: Optional subtype refinement (e.g. `class_a`, `series_a`).
    - `terms` object, required: Instrument-specific terms blob. Shape depends on `security_type` — see `CreateSecurityRequest.terms` for common keys.
    - `is_active` boolean, required: `true` when the security is in active status; `false` after a soft-delete or deactivation.
    - `authorized_shares` integer, nullable: Total shares authorized for this class, when set.
    - `outstanding_shares` integer, nullable: Shares currently issued and outstanding.
    - `created_at` string, date-time, required: Row creation timestamp (UTC).
    - `updated_at` string, date-time, required: Last-modified timestamp (UTC).
  - `at` string, required: ISO-8601 UTC timestamp
  - `createdBy` string, nullable: User ID that initiated the operation
  - `idempotentReplay` boolean: True when this envelope came from the idempotency cache — the underlying command did not execute again. False on fresh executions.

## Other responses

- `400`: Invalid request
- `401`: Authentication required
- `403`: Access denied
- `404`: Resource not found
- `409`: Idempotency-Key conflict — key reused with different body
- `422`: Validation error
- `429`: Rate limit exceeded
- `500`: Internal server error

---

[API](https://skmtc.dev/robosystems/apis/robosystems-api.md) · [All operations](https://skmtc.dev/robosystems/apis/robosystems-api/llms.txt) · [OpenAPI document](https://skmtc.dev/robosystems/apis/robosystems-api/revisions/e661e2d5ca6a?raw)
