# Grinfi.io API

Complete API reference for Grinfi.io — the all-in-one LinkedIn & email outreach platform.
Use this API to manage your CRM contacts, run outreach automations, send messages, and integrate Grinfi with your own tools.

## Authentication
All requests require a Bearer token in the `Authorization` header.
1. Log in at [leadgen.grinfi.io](https://leadgen.grinfi.io/)
2. Go to [Settings → API Keys](https://leadgen.grinfi.io/settings/api-keys)
3. Copy your key and pass it as:
   ```
   Authorization: Bearer YOUR_API_KEY
   ```


## Pagination
List endpoints support `limit` (default 20) and `offset` (default 0) query parameters. Responses include `total` count and `has_more` boolean.

## Filtering
Most list endpoints accept a `filter` object. Supported value types:
| Type | Example | SQL equivalent | |------|---------|----------------| | Scalar | `"status": "ok"` | `= 'ok'` | | Array | `"status": ["ok", "pending"]` | `IN ('ok', 'pending')` | | Object | `"created_at": {">=": "2024-01-01"}` | `>= '2024-01-01'` | | `"is_null"` | `"email": "is_null"` | `IS NULL` | | `"is_not_null"` | `"email": "is_not_null"` | `IS NOT NULL` |
Supported operators: `=`, `!=`, `<`, `<=`, `>`, `>=`, `<>`

## Rate Limits
API requests are rate-limited to **300 requests per minute** per API key. If you exceed the limit, you'll receive a `429` response. Use exponential backoff when retrying.

## Contact Deduplication
When creating contacts via upsert, the system checks for duplicates using the following field priority (first match wins):
1. `ln_member_id` (LinkedIn member ID)
2. `ln_id` (LinkedIn public ID)
3. `sn_id` (Sales Navigator ID)
4. LinkedIn nickname
5. `work_email`
6. `personal_email`
7. `name` + `company_name` combination


Version: 2.0.0
License: Copyright

## Servers

Production
```
https://leadgen.grinfi.io
```

## Security

### bearerAuth

API key from [Settings -> API Keys](https://leadgen.grinfi.io/settings/api-keys).


Type: http
Scheme: bearer
Bearer Format: JWT

## Download OpenAPI description

[Grinfi.io API](https://api.grinfi.io/_bundle/openapi.yaml)

## User

Get current authenticated user profile.


### Get current user

 - [GET /id/api/users/current](https://api.grinfi.io/openapi/user/getcurrentuser.md): Retrieve the authenticated user's profile and configuration.

## Teams

Manage workspaces (teams). Each team has its own contacts, automations, and sender profiles.


### List teams

 - [GET /id/api/teams](https://api.grinfi.io/openapi/teams/listteams.md): List all teams (workspaces) the authenticated user has access to.

### Get a team

 - [GET /id/api/teams/{id}](https://api.grinfi.io/openapi/teams/getteam.md): Get details of a specific team by ID.

### Check sender profile capacity

 - [POST /id/api/teams/{id}/check-limits](https://api.grinfi.io/openapi/teams/checkteamlimits.md): Check whether the team has capacity for the requested number of additional sender profiles within its current subscription limits. Returns monthly and yearly usage information (or null for each if the team has no active subscription on that cycle).

## API Keys

Create API keys to authenticate against the Grinfi API. Each key is a JWT token bound to your current team with a 3-year expiry. Pass the key in the `Authorization: Bearer <key>` header on every request.


### Create an API key

 - [POST /id/api/jwt-tokens/create-api-key](https://api.grinfi.io/openapi/api-keys/createapikey.md): Create a new API key bound to your current team. The returned last_token is the actual JWT to use in the Authorization: Bearer  header on subsequent requests. Tokens have a 3-year expiry.

Important: save the token immediately — it is only returned in this response and cannot be retrieved later.

## Contacts

Manage your CRM contacts (leads). Search, create, update, and organize contacts across lists and pipeline stages.

**Mass action types** for `PUT /leads/api/leads/mass-action`: `contact_add_tags`, `contact_remove_tags`, `contact_replace_tags`, `contact_change_list`, `contact_change_pipeline_stage`, `contact_change_custom_field`, `contact_add_to_flow`, `contact_cancel_from_flows`, `contact_delete`, `contact_export_csv`, `contact_mark_read`.


### Find a contact

 - [POST /leads/api/leads/lookup-one](https://api.grinfi.io/openapi/contacts/findonecontact.md): Look up a single contact by LinkedIn ID, email address, or name + company combination. At least one identifier must be provided. This is useful for checking if a contact already exists before creating a new one.

### Search contacts

 - [POST /leads/api/leads/search](https://api.grinfi.io/openapi/contacts/searchcontacts.md): Search contacts using advanced filters with pagination and sorting. Use this to find contacts by any combination of fields — name, company, email status, pipeline stage, tags, and more.

### Get a contact

 - [GET /leads/api/leads/{uuid}](https://api.grinfi.io/openapi/contacts/getlead.md): Retrieve full details of a contact by their UUID.

### Update a contact

 - [PUT /leads/api/leads/{uuid}](https://api.grinfi.io/openapi/contacts/updatelead.md): Update one or more fields on an existing contact. Only include the fields you want to change.

Important: this endpoint only accepts the standard contact fields listed below. Custom field values are silently ignored. To set custom fields use POST /leads/api/custom-field-values. Alternatively, the Upsert endpoint supports custom_fields in a single request.

### Delete a contact

 - [DELETE /leads/api/leads/{uuid}](https://api.grinfi.io/openapi/contacts/deletelead.md): Permanently delete a contact by UUID. This creates a background deletion job.

### Create or update a contact

 - [POST /leads/api/leads/upsert](https://api.grinfi.io/openapi/contacts/upsertcontact.md): Create a new contact in a list, or update an existing one if found. The contact is identified by linkedin_id. If the contact already exists and update_if_exists is true, their data will be updated. Optionally move the contact to the specified list with move_to_list.

Tip: Unlike PUT /leads/api/leads/{uuid}, this endpoint accepts custom_fields so you can set standard and custom fields in a single request.

### Mass action on contacts

 - [PUT /leads/api/leads/mass-action](https://api.grinfi.io/openapi/contacts/leadsmassaction.md): Perform a bulk action on contacts matching a filter.

Supported action types:
| Type | Payload | Description | |------|---------|-------------| | contact_add_tags | {tag_uuid} | Add a tag | | contact_remove_tags | {tag_uuid} | Remove a tag | | contact_replace_tags | {tag_uuids: [...]} | Replace all tags | | contact_change_list | {list_uuid} | Move to a different list | | contact_change_pipeline_stage | {pipeline_stage_uuid} | Change pipeline stage | | contact_change_custom_field | {custom_field_uuid, value} | Set custom field value | | contact_add_to_flow | {flow_uuid} | Add to automation | | contact_cancel_from_flows | {flow_uuids: [...]} | Cancel from automations | | contact_delete | — | Delete contacts | | contact_export_csv | — | Export to CSV | | contact_mark_read | — | Mark conversations as read |

### Count contacts

 - [POST /leads/api/leads/count](https://api.grinfi.io/openapi/contacts/countcontacts.md): Count contacts matching a filter without returning the full data. Use all: true to count every contact in the team, or pass an explicit list of contact UUIDs in ids (with all: false) to count a specific subset.

### Get team-wide engagement metrics

 - [POST /leads/api/leads/metrics](https://api.grinfi.io/openapi/contacts/getleadmetrics.md): Returns aggregated outreach metrics across the whole team for the requested period.

Important: despite accepting a filter field, this endpoint currently returns team-wide totals only — filter.sender_profile_uuid and other keys are silently ignored. The group_by field is also accepted but does not produce a per-group breakdown in the response. Plan for team-level reporting only.

For per-sender activity counts (without period filter), use: - POST /flows/api/linkedin-messages/group-counts with filter.sender_profile_uuid - GET /flows/api/tasks?filtersender_profile_uuid=&filterstatus=

### Run advanced enrichment on contacts

 - [PUT /leads/api/leads/advanced-enrichment](https://api.grinfi.io/openapi/contacts/enrichleadsadvanced.md): Enqueue advanced LinkedIn enrichment on a set of contacts. Enrichment consumes credits — returns 402 Payment Required if your team has insufficient balance.

### List enrichment queue

 - [GET /leads/api/enrichment-queue](https://api.grinfi.io/openapi/contacts/listenrichmentqueue.md): List entries in the enrichment processing queue.

### Get enrichment usage metrics

 - [POST /leads/api/enrichment-queue/metrics](https://api.grinfi.io/openapi/contacts/getenrichmentmetrics.md): Return aggregate metrics about enrichment activity for the team — currently the count of enrichment jobs queued/processed in the current calendar month.

## Companies

Manage company records in your CRM. Companies can be linked to contacts and enriched with additional data from LinkedIn.


### List companies

 - [GET /leads/api/companies](https://api.grinfi.io/openapi/companies/listcompanies.md): Retrieve a paginated list of companies in your CRM. Supports filtering by name, domain, industry, and other fields.

### Create companies

 - [POST /leads/api/companies](https://api.grinfi.io/openapi/companies/createcompanies.md): Create one or more company records. Optionally assign them to lists and a data source.

### Get a company

 - [GET /leads/api/companies/{uuid}](https://api.grinfi.io/openapi/companies/getcompany.md): Retrieve full details of a company by UUID.

### Update a company

 - [PUT /leads/api/companies/{uuid}](https://api.grinfi.io/openapi/companies/updatecompany.md): Update one or more fields on an existing company.

### Delete a company

 - [DELETE /leads/api/companies/{uuid}](https://api.grinfi.io/openapi/companies/deletecompany.md): Permanently delete a company by UUID.

### Search companies

 - [POST /leads/api/companies/list](https://api.grinfi.io/openapi/companies/searchcompanies.md): Search and filter companies with pagination. Same filtering capabilities as GET /leads/api/companies but as a POST so you can pass complex filter objects in the request body instead of query strings.

### Lookup companies

 - [POST /leads/api/companies/lookup](https://api.grinfi.io/openapi/companies/lookupcompanies.md): Find companies by LinkedIn ID, website URL, or name. Pass an array of lookup criteria — each item should contain at least one identifier.

### Get contacts by companies

 - [POST /leads/api/companies/leads](https://api.grinfi.io/openapi/companies/getcompanyleads.md): Retrieve all contacts belonging to the specified companies. Returns an object mapping company UUIDs to arrays of contacts.

### Enrich companies

 - [PUT /leads/api/companies/advanced-enrichment](https://api.grinfi.io/openapi/companies/enrichcompanies.md): Queue advanced enrichment for companies. Provide either a filter to select companies or an array of specific company UUIDs. Enrichment uses credits from your account balance.

### Mass action on companies

 - [PUT /leads/api/companies/mass-action](https://api.grinfi.io/openapi/companies/companiesmassaction.md): Perform a bulk action on companies matching a filter.

## Lists

Organize contacts into lists. Every contact must belong to a list. Use lists to segment your audience for outreach campaigns.


### List all lists

 - [GET /leads/api/lists](https://api.grinfi.io/openapi/lists/listlists.md): Retrieve all contact lists in your account. Lists are used to organize contacts into groups for outreach campaigns.

### Create a list

 - [POST /leads/api/lists](https://api.grinfi.io/openapi/lists/createlist.md): Create a new contact list.

### Get a list

 - [GET /leads/api/lists/{uuid}](https://api.grinfi.io/openapi/lists/getlist.md): Retrieve details of a specific contact list.

### Update a list

 - [PUT /leads/api/lists/{uuid}](https://api.grinfi.io/openapi/lists/updatelist.md): Rename an existing contact list.

### Delete a list

 - [DELETE /leads/api/lists/{uuid}](https://api.grinfi.io/openapi/lists/deletelist.md): Permanently delete a contact list.

### Get list metrics

 - [POST /leads/api/lists/metrics](https://api.grinfi.io/openapi/lists/getlistmetrics.md): Get lead counts for specified lists.

## Tags

Label contacts and companies with custom tags for easy filtering and segmentation.


### List tags

 - [GET /leads/api/tags](https://api.grinfi.io/openapi/tags/listtags.md): Retrieve all tags in your account.

### Create a tag

 - [POST /leads/api/tags](https://api.grinfi.io/openapi/tags/createtag.md): Create a new tag with optional color.

### Update a tag

 - [PUT /leads/api/tags/{uuid}](https://api.grinfi.io/openapi/tags/updatetag.md): Update a tag's name or color.

### Delete a tag

 - [DELETE /leads/api/tags/{uuid}](https://api.grinfi.io/openapi/tags/deletetag.md): Permanently delete a tag.

### Get tag metrics

 - [POST /leads/api/tags/metrics](https://api.grinfi.io/openapi/tags/gettagmetrics.md): Get lead and company counts for specified tags.

## Pipeline

Define and manage pipeline stages to track where each contact stands in your sales or outreach process.

**Stage categories:** `cold` (not yet contacted), `engaging` (outreach in progress), `positive` (showing interest / converted), `negative` (rejected / lost).


### List pipeline stages

 - [GET /leads/api/pipeline-stages](https://api.grinfi.io/openapi/pipeline/listpipelinestages.md): Retrieve all pipeline stages. Use the filter parameter (JSON string) to narrow results by object type or stage type.

### Create a pipeline stage

 - [POST /leads/api/pipeline-stages](https://api.grinfi.io/openapi/pipeline/createpipelinestage.md): Create a new custom pipeline stage.

### Update a pipeline stage

 - [PUT /leads/api/pipeline-stages/{uuid}](https://api.grinfi.io/openapi/pipeline/updatepipelinestage.md): Update a pipeline stage's name, category, or order.

### Delete a pipeline stage

 - [DELETE /leads/api/pipeline-stages/{uuid}](https://api.grinfi.io/openapi/pipeline/deletepipelinestage.md): Delete a custom pipeline stage.

## Custom Fields

Extend contact and company records with custom data fields. Store any additional information relevant to your workflow.

**Limits:** Maximum 100 custom fields per object type (`lead` or `company`). Field names must start with a letter or underscore, and contain only alphanumeric characters and underscores.


### List custom fields

 - [GET /leads/api/custom-fields](https://api.grinfi.io/openapi/custom-fields/listcustomfields.md): Retrieve all custom field definitions for contacts and companies.

### Create a custom field

 - [POST /leads/api/custom-fields](https://api.grinfi.io/openapi/custom-fields/createcustomfield.md): Define a new custom field for contacts or companies.

### Update a custom field

 - [PUT /leads/api/custom-fields/{uuid}](https://api.grinfi.io/openapi/custom-fields/updatecustomfield.md): Update a custom field's name or order.

### Delete a custom field

 - [DELETE /leads/api/custom-fields/{uuid}](https://api.grinfi.io/openapi/custom-fields/deletecustomfield.md): Permanently remove a custom field definition and all its values.

### Set a custom field value

 - [POST /leads/api/custom-field-values](https://api.grinfi.io/openapi/custom-fields/upsertcustomfieldvalue.md): Set (or update) a custom field value on a contact or company. Pass null as value to clear the field.

## Notes

Add internal notes to contacts or companies for your team's reference.


### List notes

 - [GET /leads/api/notes](https://api.grinfi.io/openapi/notes/listnotes.md): Retrieve notes with pagination.

### Create a note

 - [POST /leads/api/notes](https://api.grinfi.io/openapi/notes/createnote.md): Add a note to a contact or company.

### Update a note

 - [PUT /leads/api/notes/{uuid}](https://api.grinfi.io/openapi/notes/updatenote.md): Update the text of an existing note.

### Delete a note

 - [DELETE /leads/api/notes/{uuid}](https://api.grinfi.io/openapi/notes/deletenote.md): Permanently delete a note.

## Activities

Track events and interactions on contacts and companies, such as messages sent, emails opened, and status changes.


### List activities

 - [GET /leads/api/activities](https://api.grinfi.io/openapi/activities/listactivities.md): List activity records for contacts or companies. Activities track events like messages sent, emails opened, pipeline stage changes, and more.

Known activity types: pipeline_stage_changed, linkedin_message_sent, linkedin_message_replied, linkedin_connection_request_sent, linkedin_connection_request_accepted, email_sent, email_replied, email_opened, email_clicked, email_bounced, contact_enriched.

Filter by type and date range to narrow results. The payload field contains event-specific data (e.g. flow_origin, flow_uuid, pipeline stage UUIDs).

### Create an activity

 - [POST /leads/api/activities](https://api.grinfi.io/openapi/activities/createactivity.md): Create a new activity record for a contact or company.

## Blacklist

Block contacts and companies from being imported, enriched, or contacted. Blacklisted records are filtered out of automations, mass actions, and CSV imports.


### List blacklisted contacts

 - [GET /leads/api/leads-blacklist](https://api.grinfi.io/openapi/blacklist/listleadsblacklist.md): Returns blacklisted contact entries for the team. Blacklisted contacts are excluded from imports, enrichment, automations, and mass actions.

### Add contact to blacklist

 - [POST /leads/api/leads-blacklist](https://api.grinfi.io/openapi/blacklist/addleadtoblacklist.md): Blacklist a contact by LinkedIn handle, email, name, or company name. Provide at least one identifier; the entry is matched on import and outreach.

### Remove contact from blacklist

 - [DELETE /leads/api/leads-blacklist/{uuid}](https://api.grinfi.io/openapi/blacklist/deleteleadblacklistentry.md): Delete a blacklist entry by its UUID.

### List blacklisted companies

 - [GET /leads/api/companies-blacklist](https://api.grinfi.io/openapi/blacklist/listcompaniesblacklist.md): Returns blacklisted company entries for the team. Blacklisted companies are excluded from imports, enrichment, automations, and mass actions.

### Add company to blacklist

 - [POST /leads/api/companies-blacklist](https://api.grinfi.io/openapi/blacklist/addcompanytoblacklist.md): Blacklist a company by LinkedIn handle, domain, or name. Provide at least one identifier; the entry is matched on import and outreach.

### Remove company from blacklist

 - [DELETE /leads/api/companies-blacklist/{uuid}](https://api.grinfi.io/openapi/blacklist/deletecompanyblacklistentry.md): Delete a blacklist entry by its UUID.

## Data Sources

Manage LinkedIn import jobs. Data sources represent automated imports from LinkedIn searches, Sales Navigator, and other LinkedIn data.


### List data sources

 - [GET /leads/api/data-sources](https://api.grinfi.io/openapi/data-sources/listdatasources.md): List LinkedIn import jobs with pagination.

### Create a data source

 - [POST /leads/api/data-sources](https://api.grinfi.io/openapi/data-sources/createdatasource.md)

### Get a data source

 - [GET /leads/api/data-sources/{uuid}](https://api.grinfi.io/openapi/data-sources/getdatasource.md)

### Update a data source

 - [PUT /leads/api/data-sources/{uuid}](https://api.grinfi.io/openapi/data-sources/updatedatasource.md)

### Delete a data source

 - [DELETE /leads/api/data-sources/{uuid}](https://api.grinfi.io/openapi/data-sources/deletedatasource.md)

### Get data source metrics

 - [PUT /leads/api/data-sources/metrics](https://api.grinfi.io/openapi/data-sources/getdatasourcemetrics.md): Return per-data-source counts of queued, saved, duplicate, blacklisted, and error records. Pass an array of data source UUIDs in uuids. The response is a map keyed by UUID.

## File Operations

Upload and import CSV files into your CRM, and export contacts or companies to CSV. File imports run asynchronously — upload first, then trigger import-leads or import-companies. Exports return a queued job; use `/file-exports/download` once the job completes.


### Upload a CSV file

 - [POST /leads/api/file-imports/upload-csv](https://api.grinfi.io/openapi/file-operations/uploadcsvfile.md): Upload a CSV file to be imported as contacts or companies. Returns a file-import record with a UUID. Pass that UUID to import-leads or import-companies to actually create the records.

Note: the only validated type value at the time of writing is csv_leads. Companies CSV may require a different mechanism — check with support.

### Import contacts from uploaded file

 - [POST /leads/api/file-imports/{uuid}/import-leads](https://api.grinfi.io/openapi/file-operations/importleadsfromfile.md): Trigger contact import from a previously uploaded CSV file. Required field: columns — an ordered list of column-mapping objects describing how to map CSV columns to contact fields.

### Import companies from uploaded file

 - [POST /leads/api/file-imports/{uuid}/import-companies](https://api.grinfi.io/openapi/file-operations/importcompaniesfromfile.md): Trigger company import from a previously uploaded CSV file.

### Export contacts to CSV

 - [POST /leads/api/file-exports/leads](https://api.grinfi.io/openapi/file-operations/exportleadstocsv.md): Queue a CSV export of contacts matching the filter. Returns a file-export record with status queued. Once the job completes, use download to retrieve the file.

### Export companies to CSV

 - [POST /leads/api/file-exports/companies](https://api.grinfi.io/openapi/file-operations/exportcompaniestocsv.md): Queue a CSV export of companies matching the filter.

### Download an exported file

 - [POST /leads/api/file-exports/download](https://api.grinfi.io/openapi/file-operations/downloadexportfile.md): Retrieve a previously generated export file by name. The file_name is returned as part of the export record once the job completes.

## Automations

Manage outreach automation sequences. Automations define multi-step workflows that send LinkedIn messages, emails, and perform other actions on a schedule.

**Flow statuses:** `on` (active), `off` (paused), `draft`, `archived`.


### List automations

 - [GET /flows/api/flows](https://api.grinfi.io/openapi/automations/listflows.md): Retrieve all outreach automations in your account. Automations are multi-step sequences that send LinkedIn messages, emails, and other actions on a schedule.

### Get an automation

 - [GET /flows/api/flows/{flowUuid}](https://api.grinfi.io/openapi/automations/getflow.md): Retrieve full details of an automation by UUID.

### Update an automation

 - [PUT /flows/api/flows/{flowUuid}](https://api.grinfi.io/openapi/automations/updateflow.md): Update an automation's name, description, or schedule.

### Delete an automation

 - [DELETE /flows/api/flows/{flowUuid}](https://api.grinfi.io/openapi/automations/deleteflow.md): Permanently delete an automation. This cannot be undone.

### Start an automation

 - [PUT /flows/api/flows/{flowUuid}/start](https://api.grinfi.io/openapi/automations/startflow.md): Activate an automation so it begins processing contacts and executing outreach steps on its schedule.

### Stop an automation

 - [PUT /flows/api/flows/{flowUuid}/stop](https://api.grinfi.io/openapi/automations/stopflow.md): Pause an automation. Contacts already in progress will finish their current step.

### Archive an automation

 - [PUT /flows/api/flows/{flowUuid}/archive](https://api.grinfi.io/openapi/automations/archiveflow.md): Archive an automation. Archived automations cannot be started.

### Unarchive an automation

 - [PUT /flows/api/flows/{flowUuid}/unarchive](https://api.grinfi.io/openapi/automations/unarchiveflow.md): Restore an archived automation so it can be started again.

### Clone an automation

 - [POST /flows/api/flows/clone](https://api.grinfi.io/openapi/automations/cloneflow.md): Create a copy of an existing automation with a new name. The cloned automation will be in a stopped state.

### List flow contacts

 - [POST /flows/api/flows-leads/list](https://api.grinfi.io/openapi/automations/listflowleads.md): Search contacts enrolled in automations. Returns flow-lead records that link a contact to a flow with status, current node, and timing fields.

### Remove contact's flow history

 - [DELETE /flows/api/flows/leads/{leadUuid}](https://api.grinfi.io/openapi/automations/deleteflowleadhistory.md): Permanently delete all flow-lead records for a contact across all automations. This removes the enrollment history; the contact itself is not deleted.

### List automation folders

 - [GET /flows/api/flow-workspaces](https://api.grinfi.io/openapi/automations/listflowworkspaces.md): List all automation folders (workspaces) for organizing automations.

### Create automation folder

 - [POST /flows/api/flow-workspaces](https://api.grinfi.io/openapi/automations/createflowworkspace.md)

### Update automation folder

 - [PUT /flows/api/flow-workspaces/{uuid}](https://api.grinfi.io/openapi/automations/updateflowworkspace.md)

### Delete automation folder

 - [DELETE /flows/api/flow-workspaces/{uuid}](https://api.grinfi.io/openapi/automations/deleteflowworkspace.md)

### Get automation metrics

 - [POST /flows/api/flows/metrics](https://api.grinfi.io/openapi/automations/getflowmetrics.md): Retrieve performance metrics for one or more automations. Returns contact counts and task breakdowns per automation UUID.

### Add a contact to an automation

 - [POST /flows/api/flows/{flowUuid}/leads/{leadUuid}](https://api.grinfi.io/openapi/automations/addleadtoflow.md): Add an existing contact to an automation. The contact will enter the automation from the beginning of the sequence.

### Create a contact and add to automation

 - [POST /flows/api/flows/{flowUuid}/add-new-lead](https://api.grinfi.io/openapi/automations/addnewleadtoflow.md): Create a new contact and immediately add them to an automation. The contact is created in the specified list and starts the automation sequence. If skip_if_lead_exists is true, existing contacts won't be added again.

### Cancel contact from specific automations

 - [PUT /flows/api/flows/leads/{leadUuid}/cancel](https://api.grinfi.io/openapi/automations/cancelleadfromflows.md): Remove a contact from specific automations. The contact's progress in those automations will be cancelled.

### Cancel contact from all automations

 - [PUT /flows/api/flows/leads/{leadUuid}/cancel-all](https://api.grinfi.io/openapi/automations/cancelleadfromallflows.md): Remove a contact from all active automations at once.

## Flow Versions

Manage versions of automation flows. Every flow has one or more versions; each version is an immutable snapshot of the node tree and contact sources. Activating a flow version replaces the running configuration.


### List flow versions

 - [GET /flows/api/flows/{flowUuid}/flow-versions](https://api.grinfi.io/openapi/flow-versions/listflowversions.md): List all versions saved for a flow. Each version is an immutable snapshot.

### Create a flow version

 - [POST /flows/api/flows/{flowUuid}/flow-versions](https://api.grinfi.io/openapi/flow-versions/createflowversion.md): Save a new version (snapshot) of the flow's node tree and contact sources. Versions are immutable; activating a different version replaces the running config.

### Get a flow version

 - [GET /flows/api/flow-versions/{uuid}](https://api.grinfi.io/openapi/flow-versions/getflowversion.md): Retrieve a specific flow version by UUID.

### Delete a flow version

 - [DELETE /flows/api/flow-versions/{uuid}](https://api.grinfi.io/openapi/flow-versions/deleteflowversion.md): Permanently delete a flow version. Active versions cannot be deleted.

### Validate a flow node

 - [POST /flows/api/flow-versions/validate-node](https://api.grinfi.io/openapi/flow-versions/validateflownode.md): Validate a single node configuration without saving it. Useful for pre-flight checks when building a flow programmatically.

Note: the id field must be an integer, not a string.

### Validate a contact source

 - [POST /flows/api/flow-versions/validate-contact-source](https://api.grinfi.io/openapi/flow-versions/validatecontactsource.md): Validate a contact source configuration without saving it.

## Tasks

Create and manage outreach tasks such as sending LinkedIn messages or emails. Tasks can be created manually or generated by automations.

**Task types:** `linkedin_send_message`, `linkedin_send_connection_request`, `linkedin_send_inmail`, `linkedin_like_latest_post`, `linkedin_endorse_skills`, `email_send_message`, `trigger_linkedin_connection_request_accepted`.

**Task statuses:** `in_progress`, `closed`, `canceled`, `failed`, `skipped`.


### List tasks

 - [GET /flows/api/tasks](https://api.grinfi.io/openapi/tasks/listtasks.md): Retrieve outreach tasks with filtering. Tasks can be manual (created by you) or automatic (generated by automations). Filter by automation = manual or auto.

### Create a task

 - [POST /flows/api/tasks](https://api.grinfi.io/openapi/tasks/createtask.md): Create a manual outreach task. Common types: linkedin_send_message, linkedin_send_connection_request, linkedin_send_inmail, linkedin_like_latest_post, linkedin_endorse_skills.

### Get a task

 - [GET /flows/api/tasks/{uuid}](https://api.grinfi.io/openapi/tasks/gettask.md): Retrieve details of a specific task.

### Complete a task

 - [PUT /flows/api/tasks/{uuid}/complete](https://api.grinfi.io/openapi/tasks/completetask.md): Mark a manual task as completed. Only works for manual tasks.

### Cancel a task

 - [PUT /flows/api/tasks/{uuid}/cancel](https://api.grinfi.io/openapi/tasks/canceltask.md): Cancel a manual task. Only works for manual tasks.

### Mark a task as failed

 - [PUT /flows/api/tasks/{uuid}/fail](https://api.grinfi.io/openapi/tasks/failtask.md): Mark a manual task as failed. Only works for manual tasks.

### Continue automation for a contact

 - [PUT /flows/api/tasks/continue-automation](https://api.grinfi.io/openapi/tasks/continueautomation.md): Resume a paused automation for a specific contact. The contact will continue from where they were paused in the automation sequence.

### Get tasks schedule

 - [GET /flows/api/tasks/schedule](https://api.grinfi.io/openapi/tasks/gettasksschedule.md): Get the tasks schedule for a specific sender profile on a given date. Returns the timeline of scheduled tasks.

### Mass cancel tasks

 - [PUT /flows/api/tasks/mass-cancel](https://api.grinfi.io/openapi/tasks/masscanceltasks.md): Cancel multiple manual tasks at once. Only works for manual tasks.

### Mass complete tasks

 - [PUT /flows/api/tasks/mass-complete](https://api.grinfi.io/openapi/tasks/masscompletetasks.md): Mark multiple manual tasks as completed at once.

### Mass retry tasks

 - [PUT /flows/api/tasks/mass-retry](https://api.grinfi.io/openapi/tasks/massretrytasks.md): Retry multiple failed manual tasks at once.

### Mass skip tasks

 - [PUT /flows/api/tasks/mass-skip](https://api.grinfi.io/openapi/tasks/massskiptasks.md): Skip multiple manual tasks at once.

## Sender Profiles

Sender profiles represent the LinkedIn and email accounts used to send outreach messages. Each profile links a LinkedIn browser and/or email mailbox.


### List sender profiles

 - [GET /flows/api/sender-profiles](https://api.grinfi.io/openapi/sender-profiles/listsenderprofiles.md): Retrieve all sender profiles. A sender profile represents a person (with linked LinkedIn account and/or email mailbox) who sends outreach messages.

### Create a sender profile

 - [POST /flows/api/sender-profiles](https://api.grinfi.io/openapi/sender-profiles/createsenderprofile.md): Create a new sender profile with a name and optional label.

### Get a sender profile

 - [GET /flows/api/sender-profiles/{uuid}](https://api.grinfi.io/openapi/sender-profiles/getsenderprofile.md): Retrieve details of a sender profile.

### Update a sender profile

 - [PUT /flows/api/sender-profiles/{uuid}](https://api.grinfi.io/openapi/sender-profiles/updatesenderprofile.md): Update a sender profile's name, label, or schedule.

### Delete a sender profile

 - [DELETE /flows/api/sender-profiles/{uuid}](https://api.grinfi.io/openapi/sender-profiles/deletesenderprofile.md): Permanently delete a sender profile.

### Enable a sender profile

 - [PUT /flows/api/sender-profiles/{uuid}/enable](https://api.grinfi.io/openapi/sender-profiles/enablesenderprofile.md): Enable a sender profile so it can be used in automations.

### Disable a sender profile

 - [PUT /flows/api/sender-profiles/{uuid}/disable](https://api.grinfi.io/openapi/sender-profiles/disablesenderprofile.md): Disable a sender profile. It will no longer be used in automations.

## AI Agents

AI Agents classify incoming messages and contacts using a connected LLM. Agents have a prompt, an LLM configuration, and metrics about their classification accuracy.


### List AI Agents

 - [GET /flows/api/ai-agents](https://api.grinfi.io/openapi/ai-agents/listaiagents.md): Returns all AI agents in the team with their LLM configuration and metadata.

### Create an AI Agent

 - [POST /flows/api/ai-agents](https://api.grinfi.io/openapi/ai-agents/createaiagent.md): Create a new AI agent that will use the configured LLM for classification and similar tasks. Requires a connected LLM (classification_llm_uuid).

### Get an AI Agent

 - [GET /flows/api/ai-agents/{uuid}](https://api.grinfi.io/openapi/ai-agents/getaiagent.md): Retrieve a single AI agent by UUID.

### Update an AI Agent

 - [PUT /flows/api/ai-agents/{uuid}](https://api.grinfi.io/openapi/ai-agents/updateaiagent.md): Update fields on an existing AI agent. Only the supplied fields are changed.

### Delete an AI Agent

 - [DELETE /flows/api/ai-agents/{uuid}](https://api.grinfi.io/openapi/ai-agents/deleteaiagent.md): Permanently delete an AI agent. Cannot be undone.

## AI Templates

Reusable AI-driven message templates. Templates render personalized content for a given contact and sender profile, optionally calling an LLM to generate the body.


### List AI Templates

 - [GET /flows/api/ai-templates](https://api.grinfi.io/openapi/ai-templates/listaitemplates.md): List all AI templates (reusable AI-driven message snippets) for the team.

### Get an AI Template

 - [GET /flows/api/ai-templates/{uuid}](https://api.grinfi.io/openapi/ai-templates/getaitemplate.md): Retrieve a single AI template by UUID, including its prompt and LLM config.

### Update an AI Template

 - [PUT /flows/api/ai-templates/{uuid}](https://api.grinfi.io/openapi/ai-templates/updateaitemplate.md): Update fields on an existing AI template.

### Delete an AI Template

 - [DELETE /flows/api/ai-templates/{uuid}](https://api.grinfi.io/openapi/ai-templates/deleteaitemplate.md): Permanently delete an AI template.

### Render an AI Template

 - [POST /flows/api/ai-templates/render](https://api.grinfi.io/openapi/ai-templates/renderaitemplate.md): Render a template for a specific contact and sender profile. The simplest usage is to pass an existing template uuid along with lead_uuid and sender_profile_uuid — the saved template configuration is used.

For ad-hoc rendering without a saved template, pass the full set of fields (subject, body, type, llm_uuid, llm_config, prompt, enable_validation, enable_fallback, settings).

## LinkedIn Messages

Send and retrieve LinkedIn messages through your connected sender profiles.

**LinkedIn message types:** `connection_note`, `message`, `InMail`.

**Message statuses:** `new`, `in_progress`, `done`, `failed`.

**Automation field:** `auto` (sent by automation), `manual` (sent by user), `synced` (incoming message synced from LinkedIn).


### List LinkedIn messages

 - [GET /flows/api/linkedin-messages](https://api.grinfi.io/openapi/linkedin-messages/listlinkedinmessages.md): Retrieve LinkedIn messages from your unified inbox. Filter by contact, sender profile, conversation, message type (inbox/outbox), and status.

### Send a LinkedIn message

 - [POST /flows/api/linkedin-messages](https://api.grinfi.io/openapi/linkedin-messages/sendlinkedinmessage.md): Send a LinkedIn message to a contact through a sender profile. The message will be queued and sent via the linked LinkedIn account.

### Delete a LinkedIn message

 - [DELETE /flows/api/linkedin-messages/{uuid}](https://api.grinfi.io/openapi/linkedin-messages/deletelinkedinmessage.md): Delete a LinkedIn message record.

### Retry a failed LinkedIn message

 - [PUT /flows/api/linkedin-messages/{uuid}/retry](https://api.grinfi.io/openapi/linkedin-messages/retrylinkedinmessage.md): Retry sending a LinkedIn message that previously failed.

### Group counts for LinkedIn messages

 - [POST /flows/api/linkedin-messages/group-counts](https://api.grinfi.io/openapi/linkedin-messages/groupcountlinkedinmessages.md): Returns counts of LinkedIn messages grouped by status or type. Optionally scoped by sender profile via filter.sender_profile_uuid. Filter by created_at is not supported — counts are all-time totals.

Note: this endpoint is the closest available to per-sender activity counts.

## Emails

Send and retrieve emails through your connected mailboxes.

**Email types:** `inbox` (received), `outbox` (sent).


### List emails

 - [GET /emails/api/emails](https://api.grinfi.io/openapi/emails/listemails.md): Retrieve emails from your unified inbox. Filter by contact, sender profile, mailbox, type (inbox/outbox), status, and date range.

### Get an email

 - [GET /emails/api/emails/{uuid}](https://api.grinfi.io/openapi/emails/getemail.md): Retrieve full details of an email by UUID.

### Delete an email

 - [DELETE /emails/api/emails/{uuid}](https://api.grinfi.io/openapi/emails/deleteemail.md): Delete an email record.

### Send an email

 - [POST /emails/api/emails/send-email](https://api.grinfi.io/openapi/emails/sendemail.md): Send a new email to a contact through a connected mailbox.

### List email bodies

 - [GET /emails/api/email-bodies](https://api.grinfi.io/openapi/emails/listemailbodies.md): List email body records (HTML content, subject, attachments).

### Get an email body

 - [GET /emails/api/email-bodies/{uuid}](https://api.grinfi.io/openapi/emails/getemailbody.md): Get the HTML content, subject, and attachments of an email body.

### Get email thread

 - [GET /emails/api/emails/{uuid}/thread](https://api.grinfi.io/openapi/emails/getemailthread.md): Get the conversation thread for a reply email.

### Get latest emails by leads

 - [POST /emails/api/emails/latest-by-leads](https://api.grinfi.io/openapi/emails/getlatestemailsbyleads.md): Get the most recent email for each of the specified contact UUIDs.

### Get email thread for LLM

 - [POST /emails/api/emails/llm-thread](https://api.grinfi.io/openapi/emails/getemailllmthread.md): Get an email conversation thread formatted for LLM processing. Optimized for AI analysis and response generation.

## Mailboxes

Manage email mailboxes (SMTP/IMAP, Gmail, Outlook) used for sending and receiving emails in outreach campaigns.


### List mailboxes

 - [GET /emails/api/mailboxes](https://api.grinfi.io/openapi/mailboxes/listmailboxes.md): Retrieve all email mailboxes (SMTP/IMAP, Gmail, Outlook) configured in your account.

### Create a mailbox

 - [POST /emails/api/mailboxes](https://api.grinfi.io/openapi/mailboxes/createmailbox.md): Add a new SMTP/IMAP mailbox with connection settings.

### Get a mailbox

 - [GET /emails/api/mailboxes/{uuid}](https://api.grinfi.io/openapi/mailboxes/getmailbox.md): Retrieve details of a specific mailbox.

### Update a mailbox

 - [PUT /emails/api/mailboxes/{uuid}](https://api.grinfi.io/openapi/mailboxes/updatemailbox.md): Update mailbox settings such as sender name, daily limits, or connection details.

### Delete a mailbox

 - [DELETE /emails/api/mailboxes/{uuid}](https://api.grinfi.io/openapi/mailboxes/deletemailbox.md): Delete a mailbox. Optionally reassign automations to another mailbox.

### Activate a mailbox

 - [PUT /emails/api/mailboxes/{uuid}/activate](https://api.grinfi.io/openapi/mailboxes/activatemailbox.md): Enable a mailbox so it can send and sync emails.

### Deactivate a mailbox

 - [PUT /emails/api/mailboxes/{uuid}/deactivate](https://api.grinfi.io/openapi/mailboxes/deactivatemailbox.md): Disable a mailbox. It will stop sending and syncing emails.

### List mailbox errors

 - [GET /emails/api/mailbox-errors](https://api.grinfi.io/openapi/mailboxes/listmailboxerrors.md): List mailbox send/sync errors for debugging. Shows errors with timestamps and details.

## Attachments

Upload files (images, PDFs, documents) to your team's attachment storage. Uploaded attachments can be referenced by UUID when sending LinkedIn messages or emails via the `attachments` field in the request body.


### List attachments

 - [GET /flows/api/attachments](https://api.grinfi.io/openapi/attachments/listattachments.md): List files uploaded to your team's attachment storage. Attachments can be referenced by UUID when sending LinkedIn messages, emails, or from automation message nodes.

### Upload an attachment

 - [POST /flows/api/attachments](https://api.grinfi.io/openapi/attachments/uploadattachment.md): Upload a file (image, PDF, document) to attachment storage. Use multipart/form-data. Returns an attachment UUID that can be used in attachments: [{ "uuid": "..." }] when sending LinkedIn messages or emails. Supported types include images (JPG, PNG, GIF), documents (PDF, DOCX), and other common formats.

### Get an attachment

 - [GET /flows/api/attachments/{uuid}](https://api.grinfi.io/openapi/attachments/getattachment.md)

### Delete an attachment

 - [DELETE /flows/api/attachments/{uuid}](https://api.grinfi.io/openapi/attachments/deleteattachment.md)

## LinkedIn Browsers

Manage LinkedIn browser profiles used for automation. Browsers run in the cloud and execute LinkedIn actions on behalf of sender profiles.


### List LinkedIn browsers

 - [POST /browsers/api/linkedin-browsers/list](https://api.grinfi.io/openapi/linkedin-browsers/listlinkedinbrowsers.md): List all LinkedIn browser profiles with pagination.

### Get a LinkedIn browser

 - [GET /browsers/api/linkedin-browsers/{id}](https://api.grinfi.io/openapi/linkedin-browsers/getlinkedinbrowser.md)

### Update a LinkedIn browser

 - [PUT /browsers/api/linkedin-browsers/{id}](https://api.grinfi.io/openapi/linkedin-browsers/updatelinkedinbrowser.md)

### Delete a LinkedIn browser

 - [DELETE /browsers/api/linkedin-browsers/{id}](https://api.grinfi.io/openapi/linkedin-browsers/deletelinkedinbrowser.md)

### Create a LinkedIn browser

 - [POST /browsers/api/linkedin-browsers](https://api.grinfi.io/openapi/linkedin-browsers/createlinkedinbrowser.md)

### Start a browser session

 - [POST /browsers/api/linkedin-browsers/{id}/run](https://api.grinfi.io/openapi/linkedin-browsers/runlinkedinbrowser.md): Start the LinkedIn browser session. The browser will begin executing queued actions.

### Stop a browser session

 - [POST /browsers/api/linkedin-browsers/{id}/stop](https://api.grinfi.io/openapi/linkedin-browsers/stoplinkedinbrowser.md)

### Set browser proxy

 - [POST /browsers/api/linkedin-browsers/{id}/set-proxy](https://api.grinfi.io/openapi/linkedin-browsers/setlinkedinbrowserproxy.md): Change the proxy configuration for a LinkedIn browser.

### Share browser profile

 - [POST /browsers/api/linkedin-browsers/{id}/share](https://api.grinfi.io/openapi/linkedin-browsers/sharelinkedinbrowser.md): Share a LinkedIn browser profile with another team member.

## Webhooks

Configure real-time HTTP callbacks for events in your account. Webhooks send a POST (or custom method) request to your target URL whenever a specified event occurs — such as a contact replying, being enriched, or exported.


### List webhooks

 - [GET /integrations/api/webhooks](https://api.grinfi.io/openapi/webhooks/listwebhooks.md): List all webhooks configured in your account. Webhooks send HTTP requests to your target URL when specified events occur.

### Create a webhook

 - [POST /integrations/api/webhooks](https://api.grinfi.io/openapi/webhooks/createwebhook.md): Create a new webhook that fires on the specified event. Optionally add filters to narrow which contacts trigger the webhook.

### Get a webhook

 - [GET /integrations/api/webhooks/{uuid}](https://api.grinfi.io/openapi/webhooks/getwebhook.md): Retrieve full details of a webhook by UUID.

### Update a webhook

 - [PUT /integrations/api/webhooks/{uuid}](https://api.grinfi.io/openapi/webhooks/updatewebhook.md): Update one or more fields on an existing webhook. Only include the fields you want to change.

### Delete a webhook

 - [DELETE /integrations/api/webhooks/{uuid}](https://api.grinfi.io/openapi/webhooks/deletewebhook.md): Permanently remove a webhook.

### Test a webhook

 - [POST /integrations/api/webhooks/test](https://api.grinfi.io/openapi/webhooks/testwebhook.md): Send a test payload to a webhook's target URL to verify connectivity and response handling.

