# Life of a request

URL: /products/app/life-of-a-request · Id: `page:products/app/life-of-a-request`

> One click in an App, followed from the button to the Action, the Event, the webhook, the Meter and the invoice line.

Every click in an [App](/business/nouns/app) is a call to its API, and every call becomes one [Action](/business/nouns/action). Leaseline declares a `Lease` [Noun](/business/nouns/noun); follow one renewal from the button to the invoice.

## The click
Ines Duarte manages leases for Harbor Residential. She opens the lease for `Unit 5C, 76 Harbor Way`, which ends on `2026-11-05`, and presses **Renew**. The button is the form for `Lease.renew`, compiled from the [Verb](/business/nouns/verb)'s inputs: 12 months, rent up 3%.

The App sends the same call any other client sends. Harbor Residential's property software makes it too:

**As your customer**

```bash
curl -X POST https://api.leaseline.app/leases/lease_4loEed1JG4/renew \
  -H "Authorization: Bearer $LEASELINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"months":12,"increase":0.03}'
```

**As the builder**

```ts
import { $ } from 'startup-builder'

const lease = await $.Lease.renew({ lease: 'lease_4loEed1JG4', months: 12, increase: 0.03 })
```

## Who may
Three checks run before anything changes, in this order:

1. The key or the session belongs to Harbor Residential's [Tenant](/business/nouns/tenant), and so does the lease. No query crosses Tenants.
2. Ines Duarte holds the `manager` [Persona](/business/nouns/persona), whose [Role](/business/nouns/role) has the [Permission](/business/nouns/permission) to call `Lease.renew`.
3. Harbor Residential's `portfolio` plan holds an [Entitlement](/business/nouns/entitlement) to `Lease.renew` with no cap.

A failed check returns a `refused` Action naming the check, and nothing else happens. On a capped plan, the refusal names the plan that lifts the cap.

## The Action
The Verb's [Function](/business/nouns/function) runs, moves the lease from `renewing` to `renewed`, and records one Action: `done`. The Action keeps who acted, for whom, through which [Interface](/business/nouns/interface), with which key, and at which [Version](/business/nouns/version) of the definition.

**As your customer**

```json
{
  "api": "https://api.leaseline.app",
  "lease": {
    "$id": "https://api.leaseline.app/leases/lease_4loEed1JG4",
    "$type": "Lease",
    "unit": "Unit 5C, 76 Harbor Way",
    "endsOn": "2027-11-05",
    "status": "renewed"
  },
  "action": {
    "$id": "https://api.leaseline.app/actions/act_br07HsG8MG",
    "operation": "Lease.renew",
    "status": "done"
  }
}
```

**As the builder**

```bash
npx startup-builder show /actions/act_br07HsG8MG

2026-10-22T12:00:00Z  Lease.renew  by person_oJZMe5UtCH  for cus_BNY3PShL26  via app  done
```

A person's click and an [Agent](/business/nouns/agent)'s call leave the same record. Only `by` and `via` differ.

## What follows
The Action's [Event](/business/nouns/event), `Lease.renewed`, fans out to everything that waits on it:

| Who reads it | What happens |
| --- | --- |
| Harbor Residential's webhook endpoint | Receives the Event, signed `Leaseline-Signature` |
| Every open screen on that lease | Updates live, with no reload |
| A [Meter](/business/nouns/meter), when the plan meters renewals | Counts one, from `done` Actions only |
| The [audit log](/products/app/audit-log-for-admins) | Shows the Action to Harbor Residential's admins |
| The [Success Manager](/agents/customer/success-manager) agent | Stops sending renewal reminders for that unit |

A `refused` or `failed` call never reaches a Meter, so it never reaches an [Invoice](/business/nouns/invoice).

## Next
[The App lifecycle](/products/app/lifecycle) covers how a change to the App itself goes live.