> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parser-app.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrations

> Push each job to your CRM, or alert a Slack channel when a job needs review.

Integrations (`integrations:manage`) deliver job events somewhere else. `GET /v1/integrations/catalog` lists the
types, each with the JSON Schema of its `config`, its events and the module it needs.

| Type | Module | Does |
| - | - | - |
| `crm_push_generic` | `crm_sync` | Sends a summary of each job event to your CRM's REST endpoint, mapped field by field. |
| `hubspot` | `crm_sync` | Creates or updates the deal in HubSpot, connected over OAuth. |
| `salesforce` | `crm_sync` | Upserts the record (an `Opportunity` by default) in Salesforce, connected over OAuth. |
| `slack` | `notifications` | Posts review-required and failure alerts, with the reasons and a link to the result. |
| `webhook` | | The same as [`/v1/webhooks`](/guides/webhooks). |

## A generic CRM endpoint

`config.field_mapping` maps target fields (dots nest) to paths into `event`, `job` and `result`; without one, the
event's summary is sent as is. `secrets.authorization` is the `Authorization` header to send; it is write-only
and stored encrypted.

```bash theme={null}
curl -sS -X POST "$API/v1/integrations" -H "X-API-Key: $KEY" -H "Content-Type: application/json" -d '{
  "type": "crm_push_generic", "name": "Our CRM",
  "config": {"url": "https://crm.example.com/api/deals",
             "field_mapping": {"deal.monthly_revenue": "result.underwriting.avg_monthly_revenue",
                               "deal.status": "job.status"}},
  "secrets": {"authorization": "Bearer crm-token"}}'
```

## HubSpot and Salesforce

Installing answers an `authorize_url`. The integration stays `pending` until the person's consent returns. Then
each job event creates or updates the deal:

* **HubSpot** finds the deal by `match_field` (default `parser_merchant_id`, the merchant's fingerprint).
* **Salesforce** upserts `object` (default `Opportunity`) by its external-id field.

`field_mapping` sets the CRM's fields from the result (underwriting, status, positions), `result_link_field` the
result's URL, and `defaults` the fields every update carries. If the provider later refuses the grant, the
integration becomes `reauth_required`; `POST /v1/integrations/{id}/connect` gives a new consent link, and the
events in between are delivered once it is back.

## Corrections

When a reviewer [corrects](/guides/review-and-corrections) a finished job, or reverts a correction, the job emits
`job.corrected`. `crm_push_generic`, `hubspot` and `salesforce` can take it; Slack alerts do not. Every mapping
reads the corrected result: `result.*` paths see the corrected underwriting, months and rows, and `job.*` is the
event's summary as corrected, with `job.corrections` saying what changed. HubSpot and Salesforce then update the
same deal, found by its `match_field`, with the corrected figures.

| Integration | Takes `job.corrected` |
| - | - |
| `hubspot`, `salesforce` installed from now on | By default (`config.events`: `job.completed`, `job.review_required`, `job.corrected`). The deal is updated in place, so a correction never creates a second one. |
| `crm_push_generic` | Only when its `config.events` lists it. Your endpoint may create a record for each request, and a correction would then add a second one. |
| Any integration installed earlier | Only once you add it. Installed integrations keep the events they were installed with. |

To add it to an installed integration, read its `config`, add `job.corrected` to `config.events`, and send the
whole `config` back. `PATCH` replaces the config: fields you leave out take their defaults, except `events`,
which keeps the integration's own list when you leave it out.

```bash theme={null}
curl -sS "$API/v1/integrations/$INTEGRATION_ID" -H "X-API-Key: $KEY"   # copy its "config"
curl -sS -X PATCH "$API/v1/integrations/$INTEGRATION_ID" -H "X-API-Key: $KEY" -H "Content-Type: application/json" -d '{
  "config": {"url": "https://crm.example.com/api/deals",
             "field_mapping": {"deal.monthly_revenue": "result.underwriting.avg_monthly_revenue",
                               "deal.status": "job.status"},
             "events": ["job.completed", "job.review_required", "job.failed", "job.corrected"]}}'
```

The answer's `events` lists what the integration now takes. Each correction or revert is one run per
integration that takes it.

## Delivery

Each event an integration takes becomes a **run**. `5xx`, `429` and timeouts are retried on the
[webhook schedule](/guides/webhooks#delivery); a `4xx` ends the run as `dead`. `GET /v1/integrations/{id}/runs`
shows every run, and `POST /v1/integrations/{id}/test` sends a ping. Targets must be `https` on public addresses.

## Modules

Modules switch parts of the pipeline per tenant, and are all on by default: `underwriting`, `positions`, `fraud`,
`email_intake`, `email_routing`, `crm_sync` and `notifications`. A module that is off is not computed: its section
of the result is empty, `result.pipeline.modules_off` names it, and its routes answer `403`. `GET /v1/modules`
shows yours.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.