Skip to main content

Certificate Issues

Many holders fund one asset and share the income it produces. Each certificate is an undivided share of a real thing — a leased building, a fleet, a portfolio of instalment sales — not a claim on the issuer for principal plus interest.

The distinction shows up in three places the API enforces:

  • The issue must be backed. underlying_asset_value may not be less than total_value. You cannot issue more paper than there is asset behind it.
  • Distributions are income, not coupons. POST /profit divides what the asset actually earned among the certificates outstanding. A period that earned nothing distributes nothing, and there is no accrued obligation left behind.
  • Failure has a name. A missed distribution is not silently indistinguishable from a made one: POST /default exists, and a defaulted issue says so.

Base path: /api/v1/pfp/certificate-issues · Religious reading: Sukuk


Backing types

backing_type names the contract whose income the certificates share:

ValueThe certificates are backed by
leaseRental income from a leased asset
managed_investmentA managed venture's profit
partnershipA share in a joint venture
installment_saleA portfolio of instalment receivables
manufacturingAn asset under construction, paid in stages
forward_purchaseGoods paid for now and delivered later

Statuses

draft ──submit──> under_review ──review──> review_passed
│ │ │
│ └──reject──> rejected │
│ │
└──────────── offering ───────────────────────┘

v
offering ──subscribe──> (holders record subscriptions)

close_subscription (optional)
v
subscribed
│ activate ← also reachable directly from offering
v
active ──mature──> matured ──redeem──> redeemed
│ │
│ └──default──> defaulted
├──redeem_early──> redeemed
└──default──> defaulted
StatusMeaning
draftTerms recorded
under_reviewSubmitted for approval
review_passedA conclusion is attached
rejectedTerminal. Requires a reason
offeringThe subscription window is open
subscribedWindow closed, not yet placed
activePlaced; certificates are outstanding and earning
maturedThe maturity date has arrived
redeemedBought back; all positions closed
defaultedObligations not met. Requires a reason

In the secular reading offering is reachable from draft as well as review_passed.


Create an issue

POST /api/v1/pfp/certificate-issues
{
"name": "Kazan Logistics Park — Series A",
"region": "RU",
"currency": "RUB",
"backing_type": "lease",
"underlying_asset": "Logistics complex, 12 400 m², Kazan, lease to Magnit until 2032",
"underlying_asset_type": "real_estate",
"underlying_asset_value": "1800000000",
"total_value": "1500000000",
"certificate_value": "1000000",
"expected_yield": 9,
"maturity_months": 60,
"min_subscription": 5,
"max_subscription": 300,
"profit_distribution_frequency": "quarterly",
"redemption_mode": "bullet",
"early_redemption_allowed": true,
"early_redemption_penalty": "20000"
}
FieldTypeRequiredNotes
namestringIssue name
regionstringIssue region
backing_typeenumSee the table above
underlying_assetstringDescription, longer than 10 characters
underlying_asset_valuestringMinor units. Must be at least total_value
total_valuestringMinor units. Must divide by certificate_value exactly
certificate_valuestringMinor units — the face value of one certificate
expected_yieldintegerWhole percent, 1–50
maturity_monthsinteger1–360
min_subscriptionintegerMinimum certificates per application
max_subscriptionintegerCeiling per holder, across all their applications
profit_distribution_frequencyenummonthly | quarterly | semi_annually | annually
redemption_modeenumbullet | amortizing | callable
early_redemption_allowedbooleanGates redeem_early
early_redemption_penaltystringMinor units
subscription_start, subscription_enddateMay also be set at offering
originator_id, spv_id, product_iduuid
underlying_asset_type, metadata

certificates_total is derived as total_value / certificate_value, and the division must be exact.

The issue code

Each issue gets an isin field. It is not a real ISIN. A genuine ISIN is issued by a national numbering agency; the platform cannot invent one and does not pretend to. The code here is sixteen characters where ISO 6166 specifies exactly twelve, so that it cannot be mistaken for an exchange-issued identifier:

RUCRT4A7F1C9E2B3
│ │ │ └── Luhn check digit
│ │ └── ten random hex characters
│ └── three characters naming the reading: CRT secular, SKK religious
└── two-character region code

Use it internally. If the issue is listed, replace it with the real ISIN from the numbering agency.


Running a subscription

Open the window

POST /api/v1/pfp/certificate-issues/{id}/offering
{ "subscription_start": "2026-09-01", "subscription_end": "2026-10-15" }

Both dates are required. draft or review_passedoffering.

Record a subscription

POST /api/v1/pfp/certificate-issues/{id}/subscribe
{ "investor_id": "b7d1e044-92a3-4c58-8f10-3ea6c9d27b45", "certificates": 50 }

Six conditions are checked, in this order:

  1. certificates must be a positive integer.
  2. The issue must be at offering — a draft, a matured or a redeemed issue does not accept subscriptions.
  3. Today must be inside the subscription window. A closed window rejects.
  4. certificates must be at least min_subscription.
  5. max_subscription is checked against the holder's total position, not against the single application. Two applications each at the ceiling are refused, because together they exceed it. The error names how much the holder already holds.
  6. certificates must not exceed what is still unsubscribed.

Close the window (optional)

POST /api/v1/pfp/certificate-issues/{id}/close_subscription

No body. offeringsubscribed. Refused if nobody subscribed.

This step is optional — it exists so the gap between collecting applications and placing the issue is visible in reporting. activate accepts an issue directly from offering as well.

Place the issue

POST /api/v1/pfp/certificate-issues/{id}/activate
{ "issue_date": "2026-10-20" }

issue_date is optional and defaults to today. Refused if there are no subscriptions — an issue with no holders cannot be placed. Sets certificates_outstanding from what was subscribed and computes the maturity date.

offering or subscribedactive.


Distribute income

POST /api/v1/pfp/certificate-issues/{id}/profit
{ "total_profit": "33750000", "period_end_date": "2026-12-31" }

Only from active. The amount is divided by certificates_outstanding, floored, and recorded:

{
"profit_distributions": [
{
"date": "2026-12-31",
"total_profit": "33750000",
"per_certificate": "22500",
"certificates_outstanding": 1500
}
],
"total_profit_distributed": "33750000",
"actual_yield": 9,
"next_distribution_date": "2027-03-31"
}

actual_yield is recomputed on every distribution: it is what the issue has actually paid, against expected_yield, which is what was hoped for at launch. Both are whole percent. When they diverge, the second number is the one that is true.

Zero and negative amounts are refused. period_end_date is optional and defaults to today.


Ending an issue

Maturity

POST /api/v1/pfp/certificate-issues/{id}/mature

No body. activematured, but only if the maturity date has actually arrived. Calling it early is refused.

Redemption

POST /api/v1/pfp/certificate-issues/{id}/redeem
{ "redemption_date": "2031-10-20" }

Only from matured. Closes every holder's position and sets certificates_outstanding to zero.

Early redemption

POST /api/v1/pfp/certificate-issues/{id}/redeem_early
{ "redemption_date": "2029-06-01" }

Only from active, and only if early_redemption_allowed was set at creation. Otherwise:

{
"error": "unprocessable_entity",
"details": {
"early_redemption_allowed": ["досрочный выкуп условиями не предусмотрен"]
}
}

Default

POST /api/v1/pfp/certificate-issues/{id}/default
{ "reason": "Lessee insolvent; no rental income since 2028-04" }

Available from active and from matured — an issue can fail before its term or fail to pay at redemption. The reason is stored in metadata.default_reason.


List and read

GET /api/v1/pfp/certificate-issues
Query parameterValues
statusany status above
regionissue region
typeany backing_type
investor_iduuid — issues in which this holder has a subscription
envtest | prod
GET /api/v1/pfp/certificate-issues/{id}