How an agency integrates with Actum, machine to machine.
There are two halves. Inbound, your software calls the same REST routes the console calls, authenticated with a scoped API key instead of a person's session. Outbound, Actum posts signed webhooks to an endpoint you register. Both ride one event spine, so what you receive is the same fact the console shows an operator.
Credentials are issued to vetted agencies from the console's Integrations tab. If your agency is not on Actum yet, start at the agency directory.
Call the regular routes with Authorization: Bearer ak_live_…. A key is pinned to one agency, checked against a scope per route (bills:write, rent:collect, rentals:write, webhooks:manage, and so on), and shown to you exactly once at creation. Only a hash is stored, so a lost key is replaced, never recovered.
Machine traffic is rate-limited per key rather than per IP, so one integration behind a shared egress address cannot starve another. Audit rows attribute every action to api-key:<id>, which is why a key belongs to the agency and never to one person's account. Keys survive staff turnover; people do not.
Before a first listing goes live, record the seller's closing mode on its request with PATCH /api/digitization-requests/{id} (scope digitizations:write): closingMode on-inscription (the seller signs and is paid when the Land Register records the title) or at-signing, and closingChecks with registry, cadastre and idDocument, each match, mismatch or unavailable, from the documents you already hold. The listing is refused with 409 CLOSING_MODE_NOT_RECORDED until both are recorded. A seller who needs payment at signing is not listed while no title policy is available (409 CLOSING_AT_SIGNING_UNAVAILABLE). A check that does not match is flagged to Actum and does not stop the listing. The listing and the buyer's purchase page show the mode before any payment.
restrictedZone records the municipal planning certificate: status (not-in-zone, in-zone or in-zone-exempt), certificateRef and certificateDated (YYYY-MM-DD), at intake or after listing until the bearer deed is issued. The deed is not issued without it. A PATCH carrying only these fields, with no stage, records them without advancing the request.
The seller of a first listing has no Actum account on its bids, so your agency answers them on the seller's instruction. GET /api/agency/bids?agencyId=… (scope bids:read) lists the bids on the first listings you manage, newest first; add &status=open for the ones still to answer. No bidder identity is included.
PATCH /api/agency/bids/{id} (scope bids:write) answers one, with action set to accept, counter (with counterAmount, whole USD) or decline. Every call carries instruction: how and when the seller gave it, in plain text, kept in Actum's audit trail. Send expectedAmount too: the figure the seller answered (the standing counter, otherwise the bid, whole USD). If the bidder revised the bid or it was countered again since, the answer is refused with 409 and nothing changes; read the bid again and take the seller's instruction on the new figure. Repeating an answer that already stands changes nothing. An accept reserves the listing for the bidder while they pay the deposit; Actum tells the seller, and your endpoint receives digitization.sale_progressed.
A first purchase's bearer deed is issued once the property company has bought the property before the notary and the purchase has been presented to the Land Register. Your agency records both with POST /api/agency/title-registrations (scope closings:write), naming the property by propertyId: action escritura with signedOn, notary and protocol, then presentation with presentedOn, entry and registryReference. Where the sale closes on inscription, the escritura record also carries paymentLongStopOn, the payment long-stop date the deed of sale fixes (the 150th day after the signing): a different date, or none, is recorded and Actum is told, and the clocks then read the 150th day until you send it. A record that left it out may send it once, even after the bearer deed is issued, repeating the same signedOn, notary and protocol; any other change once the deed is issued is refused (409 REGISTRATION_ORDER). Dates are YYYY-MM-DD and never in the future. The registry reference must be the listing's locked one; a mismatch is refused with PRESENTATION_REFERENCE_MISMATCH. Where the purchase runs through the notary deposit, the deed of sale is refused until the buyer's money is confirmed (409 FUNDS_NOT_CONFIRMED). For a buyer who chose to sign after the fourteen days, a deed of sale signed before the date the buyer chose (the third working day after the last day of the withdrawal period) is recorded as the notary's fact and Actum is told at once; the buyer's withdrawal still works to the last day of the period, at no cost to the buyer. Actum is also told of a deed of sale recorded with no declaration from the Issuer for its day.
A record can be corrected until the bearer deed is issued, and is fixed from then on. Repeating the record that stands changes nothing. Actum records the Land Register's confirmation or refusal itself; your endpoint hears the outcome through digitization.sale_progressed.
Where the sale closed on inscription and the purchase ended by the buyer's withdrawal or an unwind before the notary paid the seller, your agency lists the property again with the same route, action relist and the old propertyId. It files a new listing request that copies the old one (the registry reference, the closing mode, the checks, the value and the photos) one step before listing, and answers 201 with the new request's id, stage and registryReference; repeating it returns the same request. List it as any other with PATCH /api/digitization-requests/[id] to listing-ready: the cost lines, the purchase file and the listing terms are copied onto the new listing then. It is refused with 409 RELIST_NOT_READY until the old bearer deed is retired, its token's burn confirmed and the Land Register's clean-up recorded (presentation-withdrawn, or once the Land Register's confirmation of the title is recorded only cancellation-filed, below); the refusal's detail names what is still to be recorded. GET /api/agency/subscription-orders?propertyId=… serves relist: null for a property that cannot be listed again here or is already listed again, otherwise ready and the missing records. It is also refused with 409 SEGMENT_NOT_CLOSED while the old property company's accounts are not at zero, 409 PROPERTY_ALREADY_LISTED once the property is listed again, 409 PRICE_ALREADY_PAID once the notary paid the seller (the sale then stands) and 409 NOT_UNDONE for a property no purchase was undone on. It does not wait for the buyer's refund. The seller is told with the withdrawal or the unwind that your agency can list the property again.
Where first listings are bought through the notary deposit, the buyer sends the whole amount to the notary's deposit account with the order's reference. Your agency records the notary's confirmation with POST /api/agency/subscription-orders (scope closings:write), naming the property by propertyId (or the order by reference), with kind (funds-received, or funds-difference for a further transfer after a short receipt), the notary's valueDate, amountMinor, currency, senderMatched (the notary's statement that the sender is the buyer) and the evidenceRef of the notary's document. Actum checks the amount against the order: a short amount holds the order for a further transfer, and the buyer is told. The response carries the outcome and the order. Money the notary records after the order has ended is recorded on that order with outcome after-end and goes back to the account it came from (for an order that ended before the deed of sale, on the proof of the end the notary already holds); your agency records that return. With no open order, where an order that lapsed and a later one that ended or completed could both be meant, name the order by reference: without it the record is refused with 409 ORDER_REFERENCE_REQUIRED. Repeating the record that stands changes nothing; other figures for a kind already recorded are refused with 409 EVENT_ALREADY_RECORDED and corrected by Actum. One exception: while the order awaits its money, a transfer the notary found from another sender (senderMatched false) does not block the next one. Record the new transfer with the same kind and the notary's new statement as its evidenceRef, and it takes that record's place; the refusal's detail names the kind when the other one is the record to replace. GET /api/agency/subscription-orders?propertyId=… returns the property's orders and what is recorded for each, with no buyer identity. Your endpoint hears digitization.sale_progressed with funds-lodged or lapsed, and with funds-unconfirmed when Actum's correction takes the confirmed money away (or lapsed when that correction ends the reservation); a later confirmation sends funds-lodged again, and a later lapse lapsed again, each as a new event.
Where the sale closes on inscription, the deed of sale is subject to the notary paying the seller's price after the Land Register records the sale. Your agency records that payment from the notary's diligencia with POST /api/agency/subscription-orders (scope closings:write), kind price-paid: valueDate (the payment date the diligencia states), receivedOn (the day the notary's record reached you), amountMinor (the price), currency, the evidenceRef of the diligencia with its protocol number, and legs: the notary's other payments of that day (each with payeeClass and amountMinor), recorded in the same transaction. The notary's fact is never refused for a check it fails: before the deed of sale it is refused (409 ESCRITURA_NOT_RECORDED), and a body that cannot be the notary's record is refused too (400 INVALID_VALUE_DATE for a date in the future, before the deed of sale, or a receipt before the payment; 400 CURRENCY_MISMATCH; 403 RELEASE_ADMIN_ONLY for a leg into Actum's or the property company's own account, which Actum records from that account's statement). Any other check that fails is named in checksFailed and the record stands. Repeating it with the same figures records only the legs the first record did not carry (201 when it records one, each leg idempotent on its own record), so you may send the payment first and its legs after; other figures are refused with 409 EVENT_ALREADY_RECORDED and corrected by Actum. Where the purchase has ended (the response carries orderEnded) or Actum must first route the payment, the payment and the legs it names are still recorded as the notary's facts and start nothing until Actum routes them; a leg the release record refuses there (an own-account leg, one already recorded with other figures) is listed in legsNotRecorded with its code, and the payment stands. Your endpoint hears price-paid; the bearer deed stays Provisional until Actum records the Land Register's confirmation too.
The same route records the notary's and the registrar's other documents after the deed of sale, each with valueDate and evidenceRef, once per purchase: condition-failed (the notary's diligencia that the payment long-stop passed with no payment), presentation-withdrawn (the application for inscription withdrawn after a failure, RH Art. 433), cancellation-filed (the application to cancel an inscription filed, LH Art. 82) and marginal-note-filed (the transfer tax's marginal note filed at the Land Register). Your operators are reminded of each registry step as it falls due. The condition fails only once the payment long-stop has passed, so a condition-failed dated on or before it cannot be the notary's proof: it is recorded, Actum checks it with you, and nothing follows from it until Actum corrects it. No clean-up is asked of you where the notary paid the seller before a withdrawal reached it, since the sale stands.
From the deed of sale on, your agency records each release the notary makes from the deposit, from the notary's settlement statement, with POST /api/agency/subscription-orders/releases (scope closings:write): propertyId (or reference), payeeClass, amountMinor, currency, releasedOn and the evidenceRef of the statement. The classes are transfer-tax, seller-vat-igic (a business seller's VAT or IGIC, paid to him with the price), ajd, notary (the escritura's fee), notary-deposit (the deposit's fee, and the diligencias' on the payment day), registry, title-policy, insurance-premium, managing-agency-fee, seller-price, seller-notary-share, seller-withholding, substitute-plusvalia, proration-to-seller (what the property company owes the seller in the payment-day statement, paid on top of the price) and listing-agency-fee. The legs into the Issuer's and the property company's own accounts are Actum's to record (403 RELEASE_ADMIN_ONLY). Nothing is released before the deed of sale (409 ESCRITURA_NOT_RECORDED). One record per class, and for registry and notary-deposit one per invoice, told apart by its evidenceRef: repeating it changes nothing, other figures are refused with 409 EVENT_ALREADY_RECORDED and corrected by Actum. A registry leg carries entriesOn, the date of the latest entry the registrar's fee note bills. A transfer-tax leg is what the notary paid; where the payment document comes to more, give its total as documentTotalMinor, and the difference is proposed to you as a draft bill of the property company. Where the sale closes on inscription, the fees, the premium and a developer's stamp duty leave at the signing, the price and what goes with it on the day the notary pays the seller, and the transfer tax after it; a release recorded out of its time is kept and named in checksFailed. Actum checks each leg against the buyer's order; the response lists any check that failed in checksFailed, and the record stands as the statement says. When a purchase is undone after the deed of sale, the repayment to the buyer is worked out from the releases recorded; once it is, a further release is refused with 409 RESTITUTION_SETTLED, so record every release the statement shows before the notary's return. The one exception: on a sale that closes on inscription where the notary's payment of the seller's price met a withdrawal, an Unwind or the end of the purchase, every release and return is recorded as the notary's fact, and Actum takes the case with counsel. Once the return is recorded, a release that would take the releases and the return above what the notary received is refused with 409 RELEASE_EXCEEDS_DEPOSIT.
When a purchase ends before the deed of sale, what the notary received goes back only on Actum's instruction, to the account it came from, with nothing taken off it. Your agency records the notary's return when it is made, with POST /api/agency/subscription-orders/returns (scope closings:write): propertyId (or reference), valueDate, amountMinor, currency, evidenceRef and an optional note. It is refused while the order stands (409 ORDER_NOT_ENDED) or holds nothing (409 NOTHING_TO_RETURN). What the notary returns within three working days of a credit under point 4 of its protocol (an excess over what is due, money from another person's account, money without the reference) is recorded the same way with protocolPoint4: true, while the order stands too; a return beyond what the notary holds over what it keeps for the order is refused with 409 RETURN_EXCEEDS_POINT_4. After the deed of sale, on an Unwind or a withdrawal, the same record is the repayment from the deposit once Actum has instructed it (409 RESTITUTION_NOT_INSTRUCTED before then). Some repayments Actum records itself: the record then answers 409 RESTITUTION_HELD, without a reason, and Actum is told; 503 SCREENING_UNAVAILABLE means try again shortly. A return that is not the whole amount is recorded and Actum is told. Where the notary's payment of the seller's price met a withdrawal, an Unwind or the end of the purchase, every return is recorded as the notary's fact and Actum takes the case with counsel, a return flagged protocolPoint4 above that point's figure included. GET /api/agency/subscription-orders?propertyId=… lists the releases with each order; an order that ended reads withdrawn, lapsed or ended, never why.
Before a buyer can press Buy, your agency records what the buyer's order shows. PATCH /api/agency/listing-terms (scope listing-terms:write) records priceEurMinor (the seller's price in euro, in cents: what the buyer sends and the deed of sale states), cadastralReferenceValueMinor (the transfer tax runs on the higher of the price and this value) and earliestSigningOn (YYYY-MM-DD, today or later, from the seller's file); null clears the last two. POST /api/agency/listing-costs records one cost of the purchase: category (transfer-tax, vat-igic, ajd, notary (the escritura's fee), notary-deposit (the deposit's fee, its own line, zero allowed: without it a buyer cannot press Buy), registry, formation-cost, title-policy, insurance-premium, managing-agency-fee or other), amountMinor, currency EUR, the basis the figure rests on, an optional rateBp for a rate-based line (650 is 6.5 %, recomputed on an accepted bid) and documentRef. PATCH and DELETE on /api/agency/listing-costs/{id} change or remove one. GET /api/agency/listing-terms?propertyId=… (scope listing-terms:read) returns the terms and the lines. While a purchase is under way the buyer's order holds what it showed, and every change is refused with 409 PURCHASE_UNDER_WAY.
Your agency records a property company's bills with POST /api/spv-bills and its recurring bills with POST /api/obligation-schedules (scope bills:write), naming the category: property-tax (the IBI), municipal-charge (the refuse charge and other municipal charges), company-tax (the company's own taxes and withholdings), insurance, condo-fee (community fees), community-levy (an extraordinary community charge), spv-upkeep (the company's statutory costs), court-order (a sum a court or an authority orders the company to pay), utility, maintenance or agency-fee.
Actum sets each bill's obligationClass from its category: tax, insurance, other-priority or other. The first three are priority bills; an unpaid priority bill can start the shortfall process, and the agency's fee and utilities do not, unless a court or an authority orders their payment. The response carries the class and its tier (1 for a priority class, 2 otherwise). A tier or a funding field in the request is accepted and ignored: the class is Actum's, and bills are not sent to the owner one by one (the owner is asked through a top-up request when the property company's money falls short).
The category reserve-topup is retired and refused with 400 CATEGORY_RETIRED. An amount the property company owes Actum is never a priority bill, so a priority category for it is refused with 400 SERVICER_NEVER_PRIORITY. A property company under the Spanish Country Schedule keeps its account in euro, so its bills are recorded in euro; another currency is refused with 400 SEGMENT_CURRENCY.
Every bill and recurring bill cites the creditor's own paper behind it: the tax notice, the community's certificate or approved budget, the insurance policy, or the invoice. A bill names at least one reference in documents, a recurring bill one in documentRef; without it the request is refused with 400 DOCUMENT_REQUIRED. Your agency keeps the paper and produces it when an owner or a seller questions the line. The bills drafted from a recurring bill carry its reference. A reference may be replaced (PATCH with documents or documentRef), never cleared. A bill recorded before this rule without a reference is paid as an ordinary bill, but it never counts toward the property company's reserve, never counts as a priority bill, is never taken from a seller's price at a sale, and is never part of a top-up request. Its responses carry the class Actum reads it in: obligationClass other and tier 2, until a reference is recorded.
Your agency records, from what it already holds at listing, each recurring bill the property company will owe once it buys the property: the property tax, the community fees, the insurance premium as quoted, the company's statutory costs as the gestoría quotes them, and any other recurring bill. POST /api/agency/purchase-file (scope purchase-file:write) records one, naming the property by propertyId, with category (property-tax, municipal-charge, condo-fee, insurance, spv-upkeep, utility or agency-fee), counterparty, amount (integer minor units per occurrence), currency, cadence, the documentRef the figure rests on, and optionally firstDueOn and note. Actum sets the obligation's class from the category. A property under the Spanish Country Schedule records its file in euro, as its bills are; another currency is refused with 400 SEGMENT_CURRENCY.
GET /api/agency/purchase-file?propertyId=… (scope purchase-file:read) returns the file and the reserve figure it gives the buyer before they buy. PATCH and DELETE on /api/agency/purchase-file/{id} update or remove one obligation, the refresh when the funds arrive. At the deed of sale the file becomes the property company's recurring obligations, each from the first amount the company owes, and is fixed from then on (409 PURCHASE_FILE_ACTIVATED).
The owner asks for offers, then chooses one of the proposals your agency presents, or none. The proposal your agency creates in the console is the offer the owner sees, and each move of the lease you record on it, in the console or with PATCH /api/agency-rental-proposals/{id} (scope rentals:write: the final lease offer, confirm-lease, active, terminated) is what the owner's record of the letting shows. The owner does not set the rent or edit the lease; they can decline a lease you have not yet recorded as active.
While a property's bearer deed is provisional, between the purchase and the Land Register's record of the title, no new tenancy starts: a new proposal, a final lease offer and a move to confirm-lease or active are refused with 409 DEED_PROVISIONAL. A lease already in place, and its rent, are unaffected.
POST /api/agency/webhooks
Authorization: Bearer ak_live_…
{
"agencyId": "ag_…",
"url": "https://example-agency.com/actum/webhook",
"topics": ["bill.paid", "rent.collected"]
}The URL must be public HTTPS. Localhost, private ranges, and hosts resolving to reserved addresses are refused at registration, and the same check runs again before every delivery. Deliveries never follow redirects; a 3xx response counts as a failed attempt. The registration response carries the endpoint plus a signing secret (whsec_…), shown once. Only topics that actually fire can be subscribed to; a declared but not-yet-live topic is refused with a 400.
GET /api/agency/webhooks?agencyId=… lists your endpoints with their health (lastSuccessAt, lastError). DELETE /api/agency/webhooks/{id} disables one; its delivery history survives.
Each event is one POST to your URL. The JSON body is an envelope: the per-topic fields documented below arrive nested under data, not at the root:
{
"id": "evt_…", // stable per business event; dedupe on this
"topic": "bill.paid",
"data": { … } // the per-topic fields listed below
}Four headers ride along.
| Actum-Topic | The event topic, for example bill.paid. |
| Actum-Event-Id | Stable per business event (evt_…). Two endpoints subscribed to the same event share it; dedupe on this. |
| Actum-Delivery-Id | Unique per delivery row (whd_…): one per endpoint per event, constant across that delivery’s retry attempts. |
| Actum-Signature | t=<unix-seconds>,v1=<hex>; see verification below. |
Respond with any 2xx within 10 seconds. Anything else, including a timeout or a redirect, counts as a failed attempt.
v1 is HMAC_SHA256(signingSecret, "<t>.<rawBody>"), hex-encoded: the same scheme Stripe uses, and the same one Actum uses to verify Stripe inbound. t is unix seconds. Verify against the raw request body, before any JSON parsing.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyActumSignature(header, rawBody, secret, toleranceSec = 5 * 60) {
const m = /^t=(\d+),v1=([0-9a-f]+)$/.exec(header ?? '');
if (!m) return false;
const [, t, v1] = m;
if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSec) return false;
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return v1.length === expected.length &&
timingSafeEqual(Buffer.from(v1, 'hex'), Buffer.from(expected, 'hex'));
}Deliveries are queued durably and attempted by a runner every five minutes. A failed attempt is retried on a backoff of 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, then daily, eight attempts in total. After the last failure the delivery is dead-lettered, visible to Actum operations, who can requeue it; the endpoint's lastError is updated.
Delivery is at-least-once. After a timeout your handler may have processed a body whose 2xx never reached us, so idempotency on Actum-Event-Id is required, not optional.
POST /api/rent-collections (scope rent:collect) records a rent receipt. The property company's money pays its bills in the order its terms set: taxes, then insurance, then the other priority bills, then the rest, oldest first within each, then its reserve, and only then the owner's balance. Your management fee is one of the non-priority bills, due on the receipt's date. When the receipt and the property's money cannot meet it in full, the part paid is booked to your earnings as before and the rest stays due, met in its turn among the non-priority bills, oldest first, from the next receipt.rent.collected carries managementFeeDueMinor and managementFeePaidMinor; managementFeeMinor keeps the paid figure for one deprecation cycle and will then be removed.
A property company whose account is kept in euro (the Spanish Country Schedule) records its rent in euro; another currency is refused with 400 SEGMENT_CURRENCY. For a commercial let, send the VAT or IGIC inside the receipt as outputTaxMinor (integer minor units): it is set aside for the company's tax return before anything else.
On a first listing whose sale closes on inscription the rent is the seller's until the notary pays him, so a receipt before that payment is refused with 409 RENT_BEFORE_PAYMENT. When the notary's payment is recorded, a lease already in place passes to the property company and becomes your agency's management mandate, on the fee its accepted offer records, and you are told to take it over; record rent from the day after the payment. A bill dated before the payment is recorded, and Actum is told: until then the seller pays the running costs.
From each rent receipt the property company sets aside the tax its gestoría expects on what the receipt leaves after the bills it paid, at the rate the gestoría gives. Your agency records that rate with POST /api/agency/company-tax-method (scope company-tax:write): propertyId, rateBp (basis points: 2500 is 25 %), basis (how the gestoría applies it), sourceDocumentRef and effectiveFrom (YYYY-MM-DD). A change is a new record from its own date. GET /api/agency/company-tax-method?propertyId=… (scope company-tax:read) lists them. The company tax bill your agency records later (category company-tax) is paid from what was set aside first.
If POST /api/rent-collections answers {"ok": false, "parked": true}, the collection settled at the custody provider but Actum's posting failed afterwards. Retry it by re-posting the same sourceRef: the custody idempotency key rent:<sourceRef> dedupes the collection, so the money is never taken twice and the posting completes on the retry.
A fresh sourceRef is a new collection. Once a live payment rail is connected, it executes a second real direct debit against the tenant.
The field lists below are the contents of the envelope's data object. Every topic carries agencyId plus the ids an external system needs, never internal snapshots. Fields ending in Minor are integer minor units encoded as strings; fields ending in Usd are whole USD numbers.
| bill.issued | A bill was sent to the owner for funding. Bills are no longer sent to the owner one by one: the property company pays them from its own money, and the owner is asked through a top-up request when that falls short. This topic no longer fires; it stays subscribable so existing registrations keep working | billId, propertyId, category, amountMinor, currency, counterparty, dueDate, funding |
| bill.paid | A bill settled, by any method | billId, propertyId, category, amountMinor, currency, counterparty, method, paidAt |
| bill.cancelled | A bill was withdrawn | billId, propertyId, category, amountMinor, currency, counterparty, wasAccrued |
| rent.collected | A rent receipt ran the waterfall | propertyId, grossMinor, currency, managementFeeDueMinor, managementFeePaidMinor, managementFeeMinor (deprecated: the paid figure), billsPaid, reserveContributionMinor, claimableMinor, sourceRef |
| rent.missed | A rent period closed with no receipt | propertyId, periodKey, expectedMinor, currency |
| shortfall.opened | Must-pay arrears exceed the property's funds | propertyId, triggerBillId, requestedBillIds, currency |
| shortfall.cure_opened | The mandate's cure right activates | propertyId, cureDeadline, curePeriodDays |
| shortfall.cure_extended | A pause of bearer deed movements suspended the cure period of a deed held in its owner's wallet; the lifting moved the deadline by the time the pause took | propertyId, cureDeadline, previousCureDeadline |
| shortfall.forced_settlement | The deed is force-listed | propertyId, reason, askingPriceUsd |
| shortfall.resolved | Arrears are covered again | propertyId, billsPaid, forcedListing |
| verification.requested | A buyer pays for a verification | requestId, propertyId |
| verification.scheduled | The inspection is scheduled | requestId, propertyId, scheduledDate |
| verification.report_published | The report goes public on the listing | requestId, propertyId |
| verification.needs_clarification | The agency needs input from the owner | requestId, propertyId |
| verification.failed | The verification cannot be completed | requestId, propertyId |
| rental.proposal_created | An agency proposes rental terms | proposalId, propertyId, monthlyRentUsd |
| rental.proposal_accepted | The owner accepts the terms | proposalId, propertyId |
| rental.proposal_declined | The owner declines the terms | proposalId, propertyId |
| rental.management_stage_changed | The lease lifecycle advances. `active` means the lease commenced | proposalId, propertyId, managementStage |
| rental.terminated | The managed rental ends | proposalId, propertyId |
| digitization.requested | An owner asks the agency to digitalize a property | requestId, contactName, contactEmail, contactPhone, locationQuery, currentlyRented, submittedAt |
| digitization.stage_changed | The pipeline advances a stage | requestId, stage |
| digitization.listing_ready | The listing is live. No bearer deed exists yet: it is issued to the buyer after the sale | requestId, propertyId |
| digitization.sale_progressed | The sale of a first listing moved: reserved (a bid accepted or a purchase started), funds-lodged (the notary confirmed the buyer’s money and the signing is booked), funds-unconfirmed (Actum corrected the record of the notary’s confirmation and the money is no longer confirmed; the listing stays reserved until it is confirmed again, when funds-lodged fires again, or the reservation lapses), lapsed (the money did not reach the notary by the deadline, or Actum’s correction of the record ended the reservation; the listing is open again), ended (the purchase ended before the deed of sale, for any other cause; the listing is open again), signed (the purchase contract), payment-possible (where the sale closes on inscription: the Land Register recorded the title and the notary can pay the seller from projectedOn; have the lender’s payoff certificate, the IBI and community certificates and the keys ready), price-paid (the notary paid the seller’s price, so the sale took effect), completed (the Land Register recorded the title and, where the sale closes on inscription, the notary’s payment of the price is recorded too), condition-failed (the notary recorded that the payment long-stop the deed of sale fixes passed with no payment; unwound follows, and the Land Register is cleaned up; never on a record dated on or before the long-stop, or while the notary’s payment of the price is recorded), unwound (the title was not recorded, or the price was not paid, and the purchase was undone) or withdrawn (the buyer withdrew after the deed of sale; never once the notary has paid the seller, when the purchase stands). After unwound or withdrawn the listing has left Actum; where the sale closed on inscription and the notary had not paid the seller, your agency can list the property again (POST /api/agency/title-registrations, action relist). funds-lodged, funds-unconfirmed, lapsed, ended, payment-possible, price-paid and condition-failed fire only where purchases run through the notary deposit. Each funds-lodged, each funds-unconfirmed and each lapsed of one purchase is its own event with its own Actum-Event-Id. Carries no buyer identity, and neither funds-unconfirmed nor ended says why | requestId, propertyId, step (reserved, funds-lodged, funds-unconfirmed, lapsed, ended, signed, payment-possible, price-paid, completed, condition-failed, unwound or withdrawn), projectedOn (YYYY-MM-DD, on payment-possible only) |
| listing.created | A deed is listed for sale. Resales of bearer deeds are not available on Actum for now, so this event is not sent | propertyId, askingPriceUsd, forced |
| listing.delisted | The seller withdraws the listing | propertyId |
| listing.sold | A sale settles, instant or by accepted bid. Resales of bearer deeds are not available on Actum for now, so this event is not sent | propertyId, priceUsd, method |
| offer.received | A bid lands on a property you manage | bidId, propertyId, amountUsd |
| offer.cancelled | Actum cancelled an open bid on a property you manage. Nothing is left to answer. Carries no bidder identity | bidId, propertyId, amountUsd |
| property.metadata_updated | Property fields change | propertyId, fields (names only, never values) |
| chain.paused | Actum paused part of the bearer deed contract: transfers (moves and retirements) or new issuance. Sent to every subscribed agency, not only one. While a transfers pause lasts, deliveries to wallets wait; sales and transfers recorded on Actum continue. | scope (transfers or mints), pausedAt, txHash |
| chain.unpaused | The pause lifted, after its public delay. Waiting deliveries go ahead. txHash identifies the pause or the lifting. A delivery Actum sends again for the same pause or lifting carries the same Actum-Event-Id, as every repeat does. | scope, pausedAt, liftedAt, txHash |
Integration questions go through your agency console. If you are already on Actum, open a request from the console and it reaches the same queue as everything else.