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

# From a won deal to a paid invoice

> Create a contact, track it as a deal, and invoice it when the deal is won

A common shape: your own system is the source of truth for customers, and
meetergo is where the commercial process lives. When a customer commits, you want
a contact, a deal in the right pipeline, and an invoice that goes out and gets
paid.

This recipe wires that up with the API and one automation.

## 1. Create the custom field that ties the two systems together

You almost certainly have your own record id. Store it on the contact so the two
systems stay reconcilable.

Custom fields are named by meetergo, not by you: a new field is created as
`newDataField`, `newDataField_1` and so on. Rename it to something you can read,
then use that name as the key.

```bash theme={null}
# Create it once, by hand or through the API
curl -X POST "https://api.meetergo.com/data-field" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{ "label": "Customer number", "fieldType": "text-single", "target": "other" }'

# Give it a stable key
curl -X PATCH "https://api.meetergo.com/data-field/16" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{ "name": "CustomerNo" }'
```

<Tip>
  `GET /data-field` lists every field with its `name`. That is the key you write
  into `additionalData` — look it up there rather than guessing.
</Tip>

## 2. Create the contact

```bash theme={null}
curl -X POST "https://api.meetergo.com/crm" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{
    "firstName": "Anna",
    "lastName": "Müller",
    "email": "anna.mueller@example.com",
    "additionalData": { "CustomerNo": "589" }
  }'
```

The response carries the contact `id`. Keep it: the deal and the invoice both
refer to it.

To find the contact again later, `GET /crm?searchTerm=anna.mueller@example.com`.
Search matches name, email, phone and notes, but **not** `additionalData` — so if
you need to look someone up by your own id, keep the mapping on your side.

## 3. Create the deal

Pipelines carry their stages, so one call gives you both ids:

```bash theme={null}
curl "https://api.meetergo.com/crm/pipelines/default" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

```bash theme={null}
curl -X POST "https://api.meetergo.com/crm/deals" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{
    "name": "Anna Müller — treatment plan",
    "pipelineId": "PIPELINE_UUID",
    "stageId": "STAGE_UUID",
    "value": 95
  }'
```

Then link the contact: `POST /crm/deals/{id}/contacts` with `{"contactId": "..."}`.

<Note>
  A deal cannot move to a different pipeline later. `stageId` must always be a
  stage of the pipeline the deal was created in, so pick the pipeline up front.
</Note>

## 4. Get told when the deal is won

There is no webhook event for deal stage changes. Use an automation instead,
which is more flexible anyway because you choose the exact stage.

In the dashboard, build a workflow with the trigger **When a deal is won** (or
**When a deal changes stage**, if you want a specific stage rather than won) and
the action **Call a webhook**, pointing at your n8n, Make, Zapier or own endpoint.
meetergo POSTs the event there, and your side does step 5.

## 5. Create, finalize and send the invoice

Three calls. See [Invoicing](/developer-docs/core-concepts/invoicing) for the full
lifecycle and why they are separate.

```bash theme={null}
# Draft, linked to both the contact and the deal
curl -X POST "https://api.meetergo.com/invoicing/documents" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{
    "kind": "invoice",
    "buyer": {
      "name": "Anna Müller",
      "email": "anna.mueller@example.com",
      "addressLine1": "Musterweg 1",
      "postalCode": "41236",
      "city": "Muttenz",
      "countryCode": "DE"
    },
    "lines": [
      { "name": "Treatment, 60 min", "quantity": 1, "unitPrice": 95 }
    ],
    "contactId": "CONTACT_UUID",
    "dealId": "DEAL_UUID"
  }'

# Number it and freeze the e-invoice
curl -X POST "https://api.meetergo.com/invoicing/documents/DOC_UUID/finalize" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{ "profile": "zugferd-en16931" }'

# Email it to the buyer
curl -X POST "https://api.meetergo.com/invoicing/documents/DOC_UUID/send" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" -d '{}'
```

<Warning>
  Finalizing fails until your invoicing settings carry a Steuernummer or USt-IdNr
  and a postal address. Set them once with `PUT /invoicing/settings`. The error
  names exactly which field is missing.
</Warning>

## 6. Payment and reminders

With Stripe, PayPal or Mollie connected, the send email carries a payment link and
the payment records itself. Bank transfers you record yourself:

```bash theme={null}
curl -X POST "https://api.meetergo.com/invoicing/documents/DOC_UUID/payments" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{ "amount": 113.05, "method": "bank_transfer" }'
```

The invoice flips to `paid` on its own once the recorded payments cover it. What
stays unpaid is picked up by Mahnwesen, once you have switched it on in
`PUT /invoicing/settings`.

## Which token do I need?

A **Personal Access Token** from Integrations & Apps. If you scope it, this
recipe needs `crm`, `forms` (for `/data-field`) and `invoicing`. Scopes are
deliberately separate: a token that reads your contacts cannot issue invoices in
your name.

## Related

* [Invoicing](/developer-docs/core-concepts/invoicing)
* [Contacts](/developer-docs/core-concepts/contacts)
