canonical: https://jentic.com/apis/espocrm.com/espocrm

# EspoCRM REST API

Jentic maintains this OpenAPI specification for EspoCRM REST API, keeping it validated and agent-ready across EspoCRM installations. EspoCRM is an open-source customer relationship management platform that runs on the customer's own server. Its REST API exposes a generic CRUD pattern keyed by entity type - Contact, Account, Lead, Opportunity, Case, and any custom entity defined in the instance - together with a relationship endpoint for linking and unlinking related records. Authentication is supported by HTTP basic credentials or an X-API-Key header.

## For AI agents

Read and write any EspoCRM entity (contacts, accounts, leads, opportunities, custom objects) and manage their relationships through a single CRUD pattern.

## Scope

Does not handle email sending, telephony, or marketing automation - use for CRUD on EspoCRM entities and their relationships only.

## Capabilities

- List, create, read, update, and delete records for any EspoCRM entity type including custom entities
- Link and unlink related records such as attaching a Contact to an Account or a Lead to a Campaign
- Page through large entity collections using offset, limit, and where-clause filters
- Retrieve related collections like all Opportunities under a given Account
- Bulk create or update CRM records during data migrations from legacy systems
- Authenticate using either basic auth or the X-API-Key header for service accounts

## Use cases

### Inbound lead capture from a website form into EspoCRM

Marketing pushes website form submissions into EspoCRM by POSTing each payload to /{entityType} with entityType set to 'Lead'. The created Lead carries the source, campaign, and contact fields, and a follow-up call to /{entityType}/{id}/{link} attaches the Lead to the originating Campaign. This avoids any custom webhook receiver inside the EspoCRM server.

Example prompt: POST a Lead to /Lead with the form fields (firstName, lastName, emailAddress, phoneNumber, source) and then POST to `/Lead/{id}/campaigns` to attach campaign id 'spring-promo'.

### Bidirectional sync between EspoCRM and an order system

Operations teams keep an external order system aligned with EspoCRM by polling /Account and /Opportunity for changes and pushing back order status updates to a custom 'Order' entity. The generic {entityType} pattern means custom objects work the same way as built-in ones, so adding new sync targets does not require new code paths. Pagination on /{entityType} uses offset and limit query parameters.

Example prompt: Loop GET /Account with offset/limit until exhaustion, then for each Account update the matching record in the order system, and write back any new Order via POST /Order.

### One-time data migration from a legacy CRM to EspoCRM

When a team is moving off a hosted CRM, they iterate the source export and call POST /Contact, POST /Account, and POST /Opportunity to recreate each record in EspoCRM. Relationships such as Contact-to-Account or Opportunity-to-Account are then established with POST /{entityType}/{id}/{link}. Because every entity uses the same CRUD pattern, the migration script is small and uniform.

Example prompt: For each row in the legacy export, POST /Contact, capture the returned id, then POST `/Contact/{id}/accounts` to attach the Account that was created earlier in the migration.

### AI agent triaging CRM records by relationship

An AI agent reviewing the sales pipeline lists Opportunities, fetches each linked Account and Contact through the relationship endpoint, and summarises stalled deals back to the rep. Through Jentic, the agent searches for the EspoCRM operations by intent rather than reading the docs, and the API key remains in your Jentic One instance. The agent can be triggered on a schedule or on demand from a sales chat tool.

Example prompt: Search Jentic for 'list EspoCRM opportunities', execute GET /Opportunity, then for each result call GET `/Opportunity/{id}/contacts` and produce a summary of the deals with no contact in the last 30 days.

## Key endpoints

| Method | Path | Description |
| --- | --- | --- |
| GET | `/{entityType}` | List records of an entity type with filters and paging |
| POST | `/{entityType}` | Create a new record of an entity type |
| GET | `/{entityType}/{id}` | Read a single record by ID |
| PUT | `/{entityType}/{id}` | Update a record by ID |
| DELETE | `/{entityType}/{id}` | Delete a record by ID |
| GET | `/{entityType}/{id}/{link}` | List related records via a relationship link |
| POST | `/{entityType}/{id}/{link}` | Attach a related record |
| DELETE | `/{entityType}/{id}/{link}` | Detach a related record |

## Key resources

- **Entities** — Generic CRUD over any entity type (Contact, Account, Lead, Opportunity, Case, custom)
- **Relationships** — List, link, and unlink related records between entities

## Why Jentic

- **Setup:** Wiring EspoCRM by hand means choosing between HTTP basic auth and the API-key request header, filling in your own host in the `/api/v1` base URL, and mapping generic entity CRUD yourself. Through Jentic you install once, import the EspoCRM REST API from the API Directory, store the API key once, and your agent calls it.
- **Permission scoping:** EspoCRM puts the entity type and record id in the URL path (/{entityType}/{id}), so a rule can pin your agent to reading or updating one entity type and nothing else. You choose the operations it may call, so a destructive one like DELETE /{entityType}/{id} is not included unless you add it.
- **Credential handling:** Your EspoCRM API key or basic auth credentials are stored once, encrypted, by your own Jentic One instance and injected at execution time. They never enter the agent's prompt, logs, or context.
- **Discovery method:** Agents search Jentic by intent such as 'create a CRM contact' or 'update a record', and Jentic returns the matching {entityType} CRUD operation with its input schema so the agent calls the right endpoint without browsing the reference docs.

## Related APIs

- **SugarCRM API** — SugarCRM is a closely comparable mid-market CRM with a similar entity model.
- **Pipedrive API** — Pipedrive offers a hosted sales pipeline CRM with deal-centric workflows.
- **Zoho CRM API** — Zoho CRM is a SaaS CRM with an extensive REST API covering modules and custom fields.

## FAQ

### Does EspoCRM provide an official OpenAPI specification?

Yes, but per installation rather than at one public address. From EspoCRM v9.3 onward each instance generates its own OpenAPI document and serves it from the `/api/v1/OpenApi` endpoint of that instance, reachable by admin users and by API users whose role enables the OpenAPI scope, or from Administration > API Users > OpenAPI spec. That document describes the entity types and custom fields configured in that one instance, so there is no single vendor-hosted spec to point an agent at. Jentic maintains this instance-independent specification of the generic entity CRUD and relationship pattern instead, and validates it. EspoCRM documents the endpoint at https://docs.espocrm.com/development/api/#openapi-specification. Get started with Jentic One, the self-hosted execution layer.

### What authentication does the EspoCRM REST API use?

EspoCRM accepts either HTTP basic auth (username and password of an EspoCRM user) or an X-API-Key header for an API user. Through Jentic, the credential is held encrypted in the vault and injected at execution time, so the agent never sees the raw key.

### Can I create custom objects through the EspoCRM REST API?

The API works with any entity type already defined in the EspoCRM instance - including custom entities you have configured in the admin panel - using the same /{entityType} CRUD pattern. Defining a brand-new entity type, however, must be done through the EspoCRM administration UI, not via this REST API.

### What are the rate limits for the EspoCRM REST API?

Because EspoCRM is self-hosted, there are no vendor-imposed rate limits - capacity is bounded only by the server you run it on. For large bulk jobs, throttle client-side and use the offset/limit parameters on /{entityType} rather than fetching everything in one request.

### How do I create a Lead in EspoCRM through Jentic?

Search Jentic for 'create a CRM lead in EspoCRM'. Jentic returns POST /{entityType} with entityType set to 'Lead' and the Lead schema. Load the operation, execute it with firstName, lastName, emailAddress, and phoneNumber, and the new Lead's id is returned in the response.

### How do I link a Contact to an Account in EspoCRM?

POST to `/Contact/{id}/accounts` with the target accountId in the body. The same /{entityType}/{id}/{link} pattern is used to attach any related entity, and a DELETE on the same path detaches it.

### Can I limit what my agent is allowed to do with the EspoCRM REST API?

Yes. Because Jentic One is self-hosted, your own rules decide which EspoCRM operations and credentials the agent may use. Since EspoCRM puts the entity type and record id in the URL path, such as /{entityType}/{id}, you can pin the agent to reading or updating a single entity type like Contact or Lead and nothing else. You choose the operations it may call, so a destructive one like DELETE /{entityType}/{id} is left out unless you add it, and the stored API key or basic auth credentials are injected at execution time rather than shown to the agent.
