Rent Receipts
Rent receipt (quittance de loyer) generation and management.
Per Art. 21 of Loi 89-462, the landlord must provide a rent receipt free of charge upon tenant request. The receipt must clearly separate rent and charges.
Key features
- Generate one receipt per active tenant, applying their
rent_sharepercentage - Automatic PDF generation (Typst) with full legal compliance
- Full payment → "Quittance de loyer", partial payment → "Reçu de loyer"
- Itemized charge breakdown by category
- Duplicate prevention (unique constraint per tenant/period)
Set a tenant's consent to electronic delivery
Records, as the landlord, whether this tenant accepts receiving their documents: rent receipts above all: by email (ALUR §6).
Consent is per tenant and per lease, and revocable: sending false
turns it off again. While it is false, the rent-receipt workflow will
not email that tenant.
Two other ways exist to reach the same flag, and they matter for how you design your UI:
POST /leases/{lease_id}/lessees/{lessee_id}/request-consent: email the tenant a one-click link so they grant it. Preferable when you want the consent evidenced as the tenant's own act.PUT /tenant/leases/{lease_id}/consent: the tenant sets it from their own portal.
Note {lessee_id} is the person's id, not the id of the
lease ↔ lessee association.
path Parameters
lease_idlessee_idThe tenant (person) id, not the lease-lessee association id.
Set a tenant's consent to electronic delivery › Request Body
electronic_delivery_consenttrue to allow email delivery, false to revoke it.
Set a tenant's consent to electronic delivery › Responses
Consent recorded: the updated association is returned.
idUnique identifier of the association
lease_idAssociated lease ID
lessee_idAssociated lessee ID
role_typeRole of the lessee in the lease
start_dateStart date of the association
created_atCreation date
updated_atLast modification date
electronic_delivery_consentWhether this tenant has consented to receiving documents: rent receipts in particular: by email (ALUR §6).
Consent is per tenant and per lease, and is revocable. Rent receipts
are not emailed to a tenant whose consent is false.
Set it as the landlord with
PUT /leases/{lease_id}/lessees/{lessee_id}/consent, ask the tenant for
it with POST /leases/{lease_id}/lessees/{lessee_id}/request-consent,
or let the tenant set it themselves from their portal with
PUT /tenant/leases/{lease_id}/consent.
rent_shareRent share for this lessee (if co-tenancy)
end_dateEnd date of the association
created_by_amendment_idAmendment ID that created this association
ended_by_amendment_idAmendment ID that ended this association
guarantor_max_amountMaximum guaranteed amount (if role = GUARANTOR)
guarantor_conditionsSpecific guarantee conditions
guarantees_lessee_idLessee ID guaranteed by this guarantor (if role = GUARANTOR)
guarantor_engagement_typeNature of the surety's undertaking (if role = GUARANTOR).
A guarantor with no guarantor_max_amount and no
guarantor_engagement_type cannot be committed: the surety deed cannot
be drawn up, and the signature pre-flight will report a
caution_incomplete blocker.
Any value other than SIMPLE or SOLIDAIRE is rejected: it is never
silently treated as "unset".
consent_updated_atWhen electronic_delivery_consent was last changed. null if never set.
Ask a tenant for their consent to email delivery
Emails the tenant a one-click link inviting them to authorise the sending of their rent receipts by email.
Prefer this over setting the flag yourself with
PUT /leases/{lease_id}/lessees/{lessee_id}/consent: the consent is
then the tenant's own act, which is what ALUR §6 asks for.
The tenant follows the link to GET /public/tenant/consent?token=…,
which is public, single-use and time-limited: no login needed.
Queued, not sent inline, hence 202. The response says the request was
accepted, not that the tenant consented.
Note {lessee_id} is the person's id.
path Parameters
lease_idlessee_idThe tenant (person) id, not the lease-lessee association id.
Ask a tenant for their consent to email delivery › Responses
Consent request accepted for delivery.
requestedSend a rent receipt to the tenant by email
Queues the emailing of an already generated receipt. The send is
asynchronous: a 202 means "accepted for delivery", not "delivered".
Poll GET /leases/{lease_id}/receipts/{receipt_id} and read
delivery_status (PENDING → QUEUED → SENT / FAILED).
Three gates, three different failures
The call is refused, with distinct status codes, when:
- the PDF is not archived yet →
400. Generate it first (POST /leases/{lease_id}/receipts/generate, orPOST …/regenerate-pdfif it was lost). - a send is already running or has succeeded →
400. OnlyPENDINGandFAILEDreceipts may be sent;QUEUEDandSENTare refused, so a double click cannot email the tenant twice. - the landlord has no rent-receipt entitlement →
402. Either a paid plan or the €4.90/year one-shot credit is required (GET /quittance-access). - the tenant has not consented to email delivery →
409. SeePOST /leases/{lease_id}/lessees/{lessee_id}/request-consent.
In every one of those cases the receipt still exists and stays readable by the tenant in their portal: refusing the email never withholds the document itself.
path Parameters
lease_idreceipt_idSend a rent receipt to the tenant by email › Responses
Send accepted; delivery continues asynchronously.
receipt_iddelivery_statusStatus right after queuing: normally QUEUED.
Rebuild the PDF of an existing rent receipt
Rebuilds and re-archives the PDF of a receipt that already exists, without creating a new receipt and without touching the amounts: the receipt keeps its frozen snapshot of rent and charges.
Use it when the document itself is the problem: the archived PDF is missing, or was produced before a template or layout fix, rather than when the figures are wrong. Wrong figures mean deleting the receipt and generating it again.
The response carries the new media_id; any URL you had cached for
the previous file is stale.
path Parameters
lease_idreceipt_idRebuild the PDF of an existing rent receipt › Responses
PDF rebuilt and archived.
receipt_idmedia_idIdentifier of the newly archived PDF.
regeneratedRead the rent-receipt automation switch of a lease
Tells you whether the automatic rent-receipt loop is on for this lease.
When enabled, the daily job reminds the landlord at the rent due date and, once payment is confirmed, generates and sends the receipt. When disabled, the lease is skipped entirely by that job: you can still generate and send receipts by hand.
The switch is per lease, not per account: a landlord can automate one property and keep another manual.
path Parameters
lease_idRead the rent-receipt automation switch of a lease › Responses
OK
enabledTurn the rent-receipt automation on or off for a lease
Flips the per-lease switch read by GET. Takes effect on the next daily
run: it does not retroactively create or cancel anything already
generated.
path Parameters
lease_idTurn the rent-receipt automation on or off for a lease › Responses
New state of the switch.
enabledList every rent receipt of the organisation
Cross-lease view of the rent receipts issued by the landlord, optionally narrowed to a period.
Each row already carries the property label and the tenant's name, so a
table can be rendered from this single call: no fan-out into
/leases, /estates and /lessees.
For the per-lease list, use GET /leases/{lease_id}/receipts.
query Parameters
period_startKeep only receipts whose period starts on or after this date.
period_endKeep only receipts whose period ends on or before this date.
List every rent receipt of the organisation › Responses
OK
receipt_idlease_idlessee_idproperty_labelLibellé lisible du bien : « nom, adresse ».
L'adresse est omise quand elle n'ajoute rien: beaucoup de bailleurs nomment leur bien par son adresse, et la coller deux fois donnait des lignes identiques pour chaque lot d'un même immeuble. Un numéro de lot présent dans le nom reste donc distinctif, alors qu'un nom qui reprend mot pour mot l'adresse se suffit à lui-même.
lessee_nameLegal name if the tenant is a company, otherwise first + last name.
period_startperiod_endtotal_dueTotal amount of the receipt, as a decimal string.
document_typeQUITTANCE when the rent was paid in full, RECU for a partial
payment: the two are legally distinct documents.
delivery_statusPENDING: generated, never sentQUEUED: send accepted, delivery in flightSENT: delivered to the tenantFAILED: delivery failed; the receipt may be sent again
sent_atWhen the receipt was emailed. null when it has not been sent.
No timezone offset is carried by this field: read it as Europe/Paris, and do not feed it to a parser that assumes UTC.
Monthly rent tracking across all active leases
The landlord's monthly dashboard: one row per active lease, telling you whether the rent for the period was received and whether the receipt has been produced and sent.
Both period_start and period_end are required: this is a view of
a given month, not an open-ended history.
payment_status is computed, not stored: paid when a payment is
recorded, otherwise late or pending depending on whether the lease's
due date for that period has passed. The due day is clamped to the
length of the month, so a lease due on the 31st falls due on 28 February.
Served by a single read model: no N+1 behind it, so it stays usable on large portfolios.
query Parameters
period_startFirst day of the period, typically the 1st of the month.
period_endLast day of the period.
Monthly rent tracking across all active leases › Responses
OK
lease_idproperty_labelLibellé lisible du bien : « nom, adresse ». L'adresse est omise quand le nom la reprend déjà.
tenant_namerent_amountRent for the period, as a decimal string.
payment_statuspaid: payment recorded for the periodpending: not received yet, due date not passedlate: due date passed and nothing recorded
The due date is the lease's payment day, clamped to the length of the month (a lease due on the 31st falls due on the 28th in February).
receipt_idReceipt for this period, null if none was generated yet.
receipt_statusDelivery status of that receipt, null when there is none.
Check whether the organisation can send rent receipts
Reads the entitlement that gates the emailing of rent receipts.
Two things can grant it: a paid plan, or the €4.90 one-shot purchase
which opens a one-year window. entitled already accounts for both:
base your UI on it, not on access_until, which is null whenever the
access comes from the plan.
Without entitlement, POST /leases/{lease_id}/receipts/{receipt_id}/send
answers 402. Generation and the tenant's own access to the document
are never gated.
Check whether the organisation can send rent receipts › Responses
OK
entitledtrue when rent receipts can be emailed: either because the plan
includes them, or because a €4.90 one-shot window is still open.
access_untilEnd of the one-shot window. null when there is none, which does
not mean "no access": entitlement may come from the plan. Always
read entitled for the decision, and use this only to display the
renewal date.
Buy one year of rent-receipt access (€4.90, one-shot)
Opens a Stripe Checkout session for the one-shot €4.90 purchase that grants a year of rent-receipt sending.
It is a one-off payment, not a subscription: nothing renews, nothing is trialled, and the window simply lapses. The price is fixed server-side: the client never chooses a Stripe price id.
Redirect the user to checkout_url. Entitlement is granted by the
Stripe webhook once the payment settles, so re-read
GET /quittance-access after the user comes back to success_url
rather than assuming access on return.
Pointless when the plan already includes rent receipts; check
GET /quittance-access first.
Buy one year of rent-receipt access (€4.90, one-shot) › Request Body
success_urlWhere Stripe returns the user after a successful payment.
cancel_urlWhere Stripe returns the user if they abandon the payment.
payment_method_typesRestrict the Stripe payment methods offered. Stripe's defaults apply when omitted.
Buy one year of rent-receipt access (€4.90, one-shot) › Responses
Checkout session created.
checkout_urlStripe Checkout URL to redirect the user to.
List my rent receipts (tenant)
Returns the receipts of the connected tenant, across all their leases. The tenant is resolved from the JWT: there is no identifier to pass, and none would be trusted.
Only receipts actually sent appear. Drafts, sends in flight and failed sends stay invisible: a tenant should not see a document their landlord has not issued to them yet.
Requires the lessee:leases:read permission.
List my rent receipts (tenant) › Responses
OK
receipt_idlease_idlessee_idproperty_labelLibellé lisible du bien : « nom, adresse ».
L'adresse est omise quand elle n'ajoute rien: beaucoup de bailleurs nomment leur bien par son adresse, et la coller deux fois donnait des lignes identiques pour chaque lot d'un même immeuble. Un numéro de lot présent dans le nom reste donc distinctif, alors qu'un nom qui reprend mot pour mot l'adresse se suffit à lui-même.
lessee_nameLegal name if the tenant is a company, otherwise first + last name.
period_startperiod_endtotal_dueTotal amount of the receipt, as a decimal string.
document_typeQUITTANCE when the rent was paid in full, RECU for a partial
payment: the two are legally distinct documents.
delivery_statusPENDING: generated, never sentQUEUED: send accepted, delivery in flightSENT: delivered to the tenantFAILED: delivery failed; the receipt may be sent again
sent_atWhen the receipt was emailed. null when it has not been sent.
No timezone offset is carried by this field: read it as Europe/Paris, and do not feed it to a parser that assumes UTC.
Download one of my rent receipts (tenant)
Streams the PDF of a receipt belonging to the connected tenant.
Ownership is checked before anything is served, and a receipt that
belongs to someone else, or that has not been sent: answers 404,
not 403: the API does not confirm that another tenant's receipt
exists.
Requires the lessee:leases:download permission.
path Parameters
receipt_idDownload one of my rent receipts (tenant) › Responses
The receipt PDF.
List my email consents, one per active lease (tenant)
For each active lease of the connected tenant: the property label and whether that tenant has consented to receiving their receipts by email.
This is what backs a "Receive my receipts by email" section with one toggle per lease showing the real stored state. Ended leases are left out: consent to a future delivery has no meaning there.
Requires the lessee:leases:read permission.
List my email consents, one per active lease (tenant) › Responses
OK
lease_idproperty_labelLibellé lisible du bien : « nom, adresse ». L'adresse est omise quand le nom la reprend déjà.
electronic_delivery_consentWhether this tenant accepts receiving their receipts by email for this lease.
Set my email consent for a lease (tenant)
The connected tenant grants or revokes, for themselves, the right to receive their receipts by email on this lease (ALUR §6: always revocable).
Only the caller's own consent is touched, and only on a lease they are
attached to; anything else answers 404.
The landlord-side equivalents are
PUT /leases/{lease_id}/lessees/{lessee_id}/consent (set it directly)
and POST /leases/{lease_id}/lessees/{lessee_id}/request-consent (ask
the tenant to do it here).
Requires the lessee:profile:write permission.
path Parameters
lease_idSet my email consent for a lease (tenant) › Request Body
electronic_delivery_consentSet my email consent for a lease (tenant) › Responses
Consent recorded: the updated association is returned.
idUnique identifier of the association
lease_idAssociated lease ID
lessee_idAssociated lessee ID
role_typeRole of the lessee in the lease
start_dateStart date of the association
created_atCreation date
updated_atLast modification date
electronic_delivery_consentWhether this tenant has consented to receiving documents: rent receipts in particular: by email (ALUR §6).
Consent is per tenant and per lease, and is revocable. Rent receipts
are not emailed to a tenant whose consent is false.
Set it as the landlord with
PUT /leases/{lease_id}/lessees/{lessee_id}/consent, ask the tenant for
it with POST /leases/{lease_id}/lessees/{lessee_id}/request-consent,
or let the tenant set it themselves from their portal with
PUT /tenant/leases/{lease_id}/consent.
rent_shareRent share for this lessee (if co-tenancy)
end_dateEnd date of the association
created_by_amendment_idAmendment ID that created this association
ended_by_amendment_idAmendment ID that ended this association
guarantor_max_amountMaximum guaranteed amount (if role = GUARANTOR)
guarantor_conditionsSpecific guarantee conditions
guarantees_lessee_idLessee ID guaranteed by this guarantor (if role = GUARANTOR)
guarantor_engagement_typeNature of the surety's undertaking (if role = GUARANTOR).
A guarantor with no guarantor_max_amount and no
guarantor_engagement_type cannot be committed: the surety deed cannot
be drawn up, and the signature pre-flight will report a
caution_incomplete blocker.
Any value other than SIMPLE or SOLIDAIRE is rejected: it is never
silently treated as "unset".
consent_updated_atWhen electronic_delivery_consent was last changed. null if never set.
Confirm rent was received (landlord, one-click, no login)
The landlord opens this from the reminder email sent at the rent due
date, and the whole month closes in one click: the payment is recorded
as PAID, the rent receipt is generated, and it is sent to the tenant:
subject to the usual entitlement and consent gates.
GET because it is opened by following a link in an email client, not
by a form. It is nonetheless a write, and a single-use one: the
token is consumed after the work succeeds, so a refresh answers 410
rather than emitting a second receipt. The consumption happens after
the action, deliberately, if generation had failed, the link is still
good for a retry.
No Authorization header: the token in the query string is the
credential.
query Parameters
tokenSingle-use token from the reminder email.
Confirm rent was received (landlord, one-click, no login) › Responses
Payment recorded and the receipt issued.
confirmedWhat was produced: the receipt and its delivery outcome.
Consent to email delivery of rent receipts (tenant, one-click, no login)
The tenant opens this from the email sent by
POST /leases/{lease_id}/lessees/{lessee_id}/request-consent, and their
consent to electronic delivery is recorded: as their own act, which is
what ALUR §6 asks for.
GET, single-use, no Authorization header: same shape as
/public/rent/confirm. A second visit answers 410.
Consent stays revocable afterwards, from the tenant portal
(PUT /tenant/leases/{lease_id}/consent) or by the landlord.
query Parameters
tokenSingle-use token from the consent request email.
Consent to email delivery of rent receipts (tenant, one-click, no login) › Responses
Consent recorded.
consentedConfirmer la réception du loyer depuis l'application
Enregistre le loyer de la période comme reçu, génère la quittance et l'envoie: en une opération.
C'est le jumeau authentifié du lien one-click envoyé par mail
(GET /public/rent/confirm), pour le bailleur qui préfère passer par
l'application. Même service applicatif derrière, donc mêmes garanties :
idempotence, gate de consentement du locataire, gate d'entitlement.
Une seule différence, et elle est volontaire : la quittance est marquée
de l'origine APP_CONFIRM au lieu d'OWNER_LINK. Le bailleur n'a pas
profité de l'automatisme, il est venu le faire lui-même: et
GET /receipts/origin-summary doit pouvoir mesurer cet écart.
Requiert la permission leases:write.
path Parameters
lease_idConfirmer la réception du loyer depuis l'application › Request Body
period_startperiod_endConfirmer la réception du loyer depuis l'application › Responses
Loyer enregistré, quittance produite.
confirmedCe qui a été produit : la quittance et l'issue de son envoi.
Répartition des quittances par origine
Compte les quittances de l'organisation selon la façon dont le loyer a été confirmé. Sert à mesurer l'adoption de la boucle automatique.
Lire part_automatique
C'est la part de OWNER_LINK parmi les quittances tracées, pas parmi
le total. Les quittances antérieures au suivi d'origine comptent dans
total mais sont exclues du dénominateur : les y laisser écraserait
mécaniquement le ratio vers le bas les premiers mois.
La valeur est null quand aucune quittance n'est tracée: null dit
« on ne sait pas », là où 0 dirait « personne n'utilise
l'automatique », ce qui serait faux.
Requiert la permission reports:read.
query Parameters
period_startNe compter que les quittances dont la période commence à partir de cette date.
period_endNe compter que les quittances dont la période finit avant cette date.
Répartition des quittances par origine › Responses
OK
period_startperiod_endtotalToutes les quittances de la période, tracées ou non.
traceesCelles dont l'origine est connue: le dénominateur de part_automatique.
Les quatre clés sont toujours présentes, à zéro si aucune quittance ne les porte.
part_automatiqueOWNER_LINK / tracees, arrondi au millième. null si tracees vaut 0.