GoodLeads CRM API

The crm API from GoodLeads — 17 operation(s) for crm.

GitHub OpenAPI

Operations 18

POST /api/v1/crm/publish Publish Leads #
GET /api/v1/crm/status/{job_id} Publish Status #
GET /api/v1/crm/field-map Field Map #
GET /api/v1/crm/connections List Connections #
POST /api/v1/crm/connections Create Connection #
POST /api/v1/crm/connections/{connection_id}/repair-presentation Repair Presentation Route #
POST /api/v1/crm/connections/{connection_id}/seed-test Seed Test Connection #
POST /api/v1/crm/connections/{connection_id}/field-set Set Zoho Field Set #
POST /api/v1/crm/connections/{connection_id}/refresh-delivered Refresh Zoho Delivered #
POST /api/v1/crm/connections/{connection_id}/remove-duplicate-leads Remove Zoho Duplicate Leads #
GET /api/v1/crm/connections/{connection_id}/delivered-records Inspect Delivered Records Route #
GET /api/v1/crm/connections/{connection_id}/delivery-summary Delivery Summary Route #
POST /api/v1/crm/connections/{connection_id}/remove-delivered Remove Delivered Route #
POST /api/v1/crm/connect/{provider} Start Self Serve Connect #
GET /api/v1/crm/connect/status/{connection_id} Self Serve Connect Status #
GET /api/v1/crm/connect/status/{connection_id}/owners Self Serve Owner Choices #
POST /api/v1/crm/connect/status/{connection_id}/owner Self Serve Set Owner #
GET /api/v1/crm/oauth/callback Oauth Callback #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/goodleads-club:goodleads-club-crm-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

goodleads-club-crm-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Formation GTM CRM API
  description: GoodLeads Formation Data Platform — scored, enriched, campaign-ready leads.
  version: 0.1.0
tags:
- name: CRM
paths:
  /api/v1/crm/publish:
    post:
      tags:
      - CRM
      summary: Publish Leads
      description: 'Publish selected leads to a connected CRM.


        Provide entity_ids for specific leads, or set include_all_matching=True

        with filters to publish the whole filtered set — resolved server-side,

        same contract as POST /leads/export. state is optional: omit it to push

        every matching lead across all live states (e.g. an industry-only filter).


        `connection_id` is required — delivery runs through the engine (per-record

        ledger, pacing, retries) against that connection. Returns immediately with

        a durable job_id for polling. dry_run counts without sending.'
      operationId: publish_leads_api_v1_crm_publish_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishRequest'
        required: true
      responses:
        '202':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublishResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
      - APIKeyHeader: []
  /api/v1/crm/status/{job_id}:
    get:
      tags:
      - CRM
      summary: Publish Status
      description: 'Check CRM publish job progress — durable, survives restarts.


        A job left `running` past the staleness window reports `interrupted`: the

        process died mid-push and its per-record ledger rows are intact. The

        engine''s resume watchdog relaunches interrupted jobs automatically;

        re-pushing the same selection is also safe (delivered leads are skipped).'
      operationId: publish_status_api_v1_crm_status__job_id__get
      parameters:
      - name: job_id
        in: path
        required: true
        schema:
          type: string
          title: Job Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/field-map:
    get:
      tags:
      - CRM
      summary: Field Map
      description: Return HubSpot field mapping configuration.
      operationId: field_map_api_v1_crm_field_map_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /api/v1/crm/connections:
    get:
      tags:
      - CRM
      summary: List Connections
      description: List CRM connections. Client secrets and access tokens are never returned.
      operationId: list_connections_api_v1_crm_connections_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/ConnectionResponse'
                type: array
                title: Response List Connections Api V1 Crm Connections Get
      security:
      - APIKeyHeader: []
    post:
      tags:
      - CRM
      summary: Create Connection
      description: 'Register a partner CRM connection.


        Two shapes, chosen by `credential_kind`:

        - **oauth** (Lawmatics): store the partner''s app credentials and mint the

        `authorize_url` they click (while logged in to their CRM) to grant access;

        the callback endpoint below finishes the handshake.

        - **api_key** (Instantly): store the partner''s pasted scoped key (encrypted)

        and go straight to `connected` — no app to create, no callback. The

        partner''s only action is pasting the key.'
      operationId: create_connection_api_v1_crm_connections_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectionCreateRequest'
        required: true
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConnectionResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
      - APIKeyHeader: []
  /api/v1/crm/connections/{connection_id}/repair-presentation:
    post:
      tags:
      - CRM
      summary: Repair Presentation Route
      description: 'One-time person-first touch-up for already-delivered matters.


        Re-titles each ledgered matter to the person''s name and fills its native

        basics (partner feedback 2026-07-23: cards must show individuals, matching

        the account''s other pipelines). Idempotent; paced; per-record results.'
      operationId: repair_presentation_route_api_v1_crm_connections__connection_id__repair_presentation_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connections/{connection_id}/seed-test:
    post:
      tags:
      - CRM
      summary: Seed Test Connection
      description: 'Verify a live connection end to end with one synthetic seed lead.


        Server-side by design: access tokens are EncryptedText and never leave

        the server, so the whole deliver → read-back → delete cycle runs here.

        Delivery goes through the real adapter (`ADAPTERS[provider].deliver_one`)

        but writes NO CrmDelivery / CrmPublishJob rows — this is a probe, not a

        delivery. Returns the exhaustive checklist ({check, expected, actual, ok}

        per field/tag/placement/link), `passed`, distilled `mismatches`, the

        `discoveries` map (candidate payload variants tried in-run, with the

        empirically working one named per construct), and the cleanup report —

        deletion failures surface as `leftover_records`.'
      operationId: seed_test_connection_api_v1_crm_connections__connection_id__seed_test_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      requestBody:
        content:
          application/json:
            schema:
              anyOf:
              - $ref: '#/components/schemas/SeedTestRequest'
              - type: 'null'
              title: Req
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connections/{connection_id}/field-set:
    post:
      tags:
      - CRM
      summary: Set Zoho Field Set
      description: 'Choose which fields a Zoho connection receives: `standard` (the twenty a

        client''s sales team keeps — every client''s default) or `showcase` (those plus

        every other column of the master file — our own demo account). The fields are

        created on the next push; records already in Zoho pick them up through

        refresh-delivered.'
      operationId: set_zoho_field_set_api_v1_crm_connections__connection_id__field_set_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FieldSetRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connections/{connection_id}/refresh-delivered:
    post:
      tags:
      - CRM
      summary: Refresh Zoho Delivered
      description: 'Re-send every field EXCEPT the phone and email to Leads we already delivered.


        The upsert keys on the GoodLeads ID, so each record updates in place, never

        duplicates. Phone and email are left out on purpose: how to reach the owner

        stays exactly as the order that delivered it bought it. Used when the field

        set grows (showcase) or a fact that was missing at delivery now exists.

        A Lead with an empty Phone gets its OWN Mobile copied in (the number the

        order delivered — never a newer one of ours).

        Paged by `limit` / `offset` (oldest delivery first) so one call fits a request.'
      operationId: refresh_zoho_delivered_api_v1_crm_connections__connection_id__refresh_delivered_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 25
          title: Limit
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          default: 0
          title: Offset
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connections/{connection_id}/remove-duplicate-leads:
    post:
      tags:
      - CRM
      summary: Remove Zoho Duplicate Leads
      description: 'Find — and with dry_run=false delete — extra Zoho Leads carrying one of our

        GoodLeads IDs that are NOT the Lead our ledger delivered. Only our own copies

        can match: the GoodLeads ID is a field we write. Dry run by default; the

        report lists, per record, the Lead kept and the copies found.


        Built to clean up the 2026-11-06 refresh, which inserted a second Lead for

        each of 30 records; kept as the tool that proves a connection holds one Lead

        per record.'
      operationId: remove_zoho_duplicate_leads_api_v1_crm_connections__connection_id__remove_duplicate_leads_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      - name: dry_run
        in: query
        required: false
        schema:
          type: boolean
          default: true
          title: Dry Run
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connections/{connection_id}/delivered-records:
    get:
      tags:
      - CRM
      summary: Inspect Delivered Records Route
      description: 'Read back what the CRM actually holds for records we already delivered.


        Ground truth, not inference: for the connection''s most recent delivered

        records (their Matter ids come from the crm_delivery ledger), read each

        Matter + its linked Contact + Company from the CRM with fields=all and

        report exactly what''s on them — native fields, custom-field values (by

        label), the channel/address collections, the tag. Strictly READ-ONLY (no

        writes, no ledger rows). Admin-gated; paced under the rate limit.'
      operationId: inspect_delivered_records_route_api_v1_crm_connections__connection_id__delivered_records_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 5
          title: Limit
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connections/{connection_id}/delivery-summary:
    get:
      tags:
      - CRM
      summary: Delivery Summary Route
      description: 'How many leads this connection has ever received — the delivery ledger,

        aggregated. The question every partner conversation starts with.


        Pure DB read, no partner API calls. `delivered_total` counts

        status=''delivered'' ledger rows — the exact never-twice set the engine

        dedups against, so it IS "records this partner holds from us." Failed

        attempts are reported separately (they never block a retry and are not

        partner inventory). Weekly buckets + the recent publish jobs give the

        push history at a glance.'
      operationId: delivery_summary_route_api_v1_crm_connections__connection_id__delivery_summary_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connections/{connection_id}/remove-delivered:
    post:
      tags:
      - CRM
      summary: Remove Delivered Route
      description: 'Delete specific already-delivered leads from the partner CRM and drop

        their ledger rows — for records sent in error, off-target, or a removal

        request. Uses the connection''s stored key server-side, so it needs DELETE

        scope on that key (a create-only key gets a 401, reported per-record, never

        silent). Instantly and Zoho. Admin-gated. Dropping the ledger row makes

        the record cleanly re-deliverable later if it becomes a wanted lead.'
      operationId: remove_delivered_route_api_v1_crm_connections__connection_id__remove_delivered_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RemoveDeliveredRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connect/{provider}:
    post:
      tags:
      - CRM
      summary: Start Self Serve Connect
      description: 'Start connecting the buyer''s own CRM from checkout: returns the provider''s

        approval link. After Approve, the buyer lands back on `return_to` with

        `crm=connected&connection=` (or `crm=declined`).'
      operationId: start_self_serve_connect_api_v1_crm_connect__provider__post
      parameters:
      - name: provider
        in: path
        required: true
        schema:
          type: string
          title: Provider
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SelfServeConnectRequest'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connect/status/{connection_id}:
    get:
      tags:
      - CRM
      summary: Self Serve Connect Status
      description: 'What the checkout shows: connected or not, which account, who owns new Leads.'
      operationId: self_serve_connect_status_api_v1_crm_connect_status__connection_id__get
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connect/status/{connection_id}/owners:
    get:
      tags:
      - CRM
      summary: Self Serve Owner Choices
      description: 'Who can own the new Leads: the account''s Lead assignment rules (plus the

        connecting user, which is Zoho''s default when no rule is chosen).'
      operationId: self_serve_owner_choices_api_v1_crm_connect_status__connection_id__owners_get
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/connect/status/{connection_id}/owner:
    post:
      tags:
      - CRM
      summary: Self Serve Set Owner
      description: Save who owns the new Leads. A rule id must be one of the account's rules.
      operationId: self_serve_set_owner_api_v1_crm_connect_status__connection_id__owner_post
      parameters:
      - name: connection_id
        in: path
        required: true
        schema:
          type: string
          title: Connection Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OwnerChoice'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/crm/oauth/callback:
    get:
      tags:
      - CRM
      summary: Oauth Callback
      description: 'Public OAuth redirect target — finishes the handshake, shows the partner a page.


        Unauthenticated by design: the partner''s browser lands here from the CRM''s

        authorize screen. The `state` token (unique, unguessable, minted at

        registration) is what ties the request to a known connection; anything

        that doesn''t match gets a plain-language error page and nothing else.'
      operationId: oauth_callback_api_v1_crm_oauth_callback_get
      parameters:
      - name: state
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: State
      - name: code
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Code
      - name: error
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Error
      - name: accounts-server
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Accounts-Server
      - name: location
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Location
      responses:
        '200':
          description: Successful Response
          content:
            text/html:
              schema:
                type: string
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    SeedTestRequest:
      properties:
        run_suffix:
          anyOf:
          - type: string
          - type: 'null'
          title: Run Suffix
        campaign_name:
          anyOf:
          - type: string
          - type: 'null'
          title: Campaign Name
      type: object
      title: SeedTestRequest
    OwnerChoice:
      properties:
        rule_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Rule Id
      type: object
      title: OwnerChoice
    ConnectionCreateRequest:
      properties:
        label:
          type: string
          title: Label
        provider:
          type: string
          title: Provider
          default: lawmatics
        credential_kind:
          type: string
          title: Credential Kind
          default: oauth
        client_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Client Id
        client_secret:
          anyOf:
          - type: string
          - type: 'null'
          title: Client Secret
        redirect_uri:
          anyOf:
          - type: string
          - type: 'null'
          title: Redirect Uri
        api_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Api Key
        campaign_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Campaign Id
      type: object
      required:
      - label
      title: ConnectionCreateRequest
    PublishRequest:
      properties:
        state:
          anyOf:
          - type: string
          - type: 'null'
          title: State
        entity_ids:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Entity Ids
        include_all_matching:
          type: boolean
          title: Include All Matching
          default: false
        filters:
          items:
            additionalProperties: true
            type: object
          type: array
          title: Filters
          default: []
        include_non_operating:
          type: boolean
          title: Include Non Operating
          default: false
        include_existing:
          type: boolean
          title: Include Existing
          default: false
        include_registrations:
          type: boolean
          title: Include Registrations
          default: false
        dry_run:
          type: boolean
          title: Dry Run
          default: false
        connection_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Connection Id
      type: object
      title: PublishRequest
    FieldSetRequest:
      properties:
        field_set:
          type: string
          title: Field Set
      type: object
      required:
      - field_set
      title: FieldSetRequest
    ConnectionResponse:
      properties:
        connection_id:
          type: string
          title: Connection Id
        provider:
          type: string
          title: Provider
        label:
          type: string
          title: Label
        status:
          type: string
          title: Status
        credential_kind:
          type: string
          title: Credential Kind
        redirect_uri:
          anyOf:
          - type: string
          - type: 'null'
          title: Redirect Uri
        authorize_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Authorize Url
        connected_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Connected At
      type: object
      required:
      - connection_id
      - provider
      - label
      - status
      - credential_kind
      title: ConnectionResponse
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    PublishResponse:
      properties:
        job_id:
          type: string
          title: Job Id
        status:
          type: string
          title: Status
        status_url:
          type: string
          title: Status Url
      type: object
      required:
      - job_id
      - status
      - status_url
      title: PublishResponse
    RemoveDeliveredRequest:
      properties:
        entity_ids:
          items:
            type: string
          type: array
          title: Entity Ids
      type: object
      required:
      - entity_ids
      title: RemoveDeliveredRequest
    SelfServeConnectRequest:
      properties:
        email:
          type: string
          title: Email
        return_to:
          type: string
          title: Return To
          default: /buy.html
      type: object
      required:
      - email
      title: SelfServeConnectRequest
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key