# Built-in services

Jadpo gives your app some common backend features itself, so you don't
install a library or write your own: feature flags, rate limits, files,
an audit trail, telemetry, email, documents, search and bot protection.
Each is part of Jadpo's runtime and runs inside your app's process, never
as a separate container. Some reach an outside service, such as a mail
provider, through a connection you declare in `app.jadpo`.
[How packages, connections, capabilities and services fit together](how-integrations-fit-together.md)
says how the pieces relate.

A feature is built in only when the compiler gains something by knowing
about it: a mistake becomes a compile error, a test or a report is
generated, policy or erasure reaches it, or the runtime does the work
with nothing for you to write. Saving a library install isn't enough.
The table lists each feature, why it is built in, and where you set it
up. [What is built](built-in-services-built.md) says which of them work today.

| Feature | Native? | Why | Where it lives |
|---|---|---|---|
| Feature flags | Yes | Misspelt flags are errors; both branches tested; expired flags reported; one-step removal | Root `flags.jadpo`; read as `flags.name`; state in the app's database, not a capability |
| Rate limits | Yes | The route knows the caller; 429 is already a failure kind; limits appear in OpenAPI | `rate_limit:` on an API or route; counted in the cache store, or Cloudflare's binding on Workers |
| Files | Yes, through the `files` capability | Size and type checked; policy and erasure reach the bytes; signed links generated | `File` fields; a `files` connection in `app.jadpo`: the S3 driver, or the disk driver on native |
| Audit trail | Yes | The compiler sees every write and its caller; personal fields hashed | `audit:` section on an entity; `AuditEntryRecorded` when something listens |
| Telemetry | Yes, with one settings section | Every route, query, action, job and provider call is known | `telemetry:` in `application { }`; custom metrics in a domain's `monitoring.jadpo` |
| Path IDs and monitoring thresholds | Yes | Every path is known, so it can be named, sampled and given limits | Generated runtime; a monitoring file per domain |
| Caches | Yes ([Caches](caches.md)) | What may be cached, and what never is, is the language's | Redis-compatible connections; [Caches: drivers and what they hold](caches-drivers-and-what-they-hold.md) |
| Email | Yes, through the `email` capability | Templates typed against translations; delivered after commit; any provider without code changes | `type X = EmailMessage` in `emails/`; an `email` connection in `app.jadpo` |
| Documents | Yes, through the `documents` capability | Templates typed and translated as email's; rendered in subscribers | `type X = Document` in `documents/`; a `documents:` connection in `app.jadpo` |
| Search | Yes, through the `search` capability | Index, query and migration generated from one declaration; results always pass policy | `search:` section on an entity; PostgreSQL unless it names an engine |
| Bot protection | Yes, through the `bot_check` capability | Jadpo's own public endpoints need it; the token never enters a route's input | `bot_check:` in `application { }`, `bot_check: true` on a route or feature |
| Outgoing webhooks | Yes | Payloads typed from events; signing and retries generated; one guarded network exception | Later, through `publishing` |
| Field encryption | Yes | Encrypted fields kept out of logs, indexes and filters | [Encrypted fields](encrypted-fields.md) |
| Realtime, admin screens, payments, CMS, analytics, quotas, media transformations | No, or later | The compiler gains little, or the feature is not a backend's | Not built in; media services (Cloudinary, Uploadcare) are ordinary packages |
