Cogram Directory API

Directory reconciliation: propose and apply the company link that contacts created outside a transmittal send are missing.

Operations 2

POST /directory/contact-company-links Apply proposed contact-to-company links #

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/cogram-com:cogram-com-directory-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

cogram-com-directory-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Cogram Directory API
  description: 'API for integrating with Cogram. Every key is scoped to one organization.


    - **Auth**: `Authorization: Bearer `. Admins mint keys in Organization

    Settings → Integrations → API Keys.

    - **Pagination**: `page` (1-indexed) + `page_size` (default 50, max 100); returns

    `{"data": [...], "total": N, "page": N, "page_size": N}`. `total` = all matches.

    - **Errors**: `{"error": "", "message": ""}`. Branch on `error`; `message`

    wording may change.

    - **Rate limit**: per key, 1000 req/min by default. `429` carries `Retry-After`,

    `X-RateLimit-Limit`, `X-RateLimit-Remaining`.

    - **Attribution**: optional `X-Forwarded-User` header (≤200 chars) names the end user

    behind the call in Cogram''s audit trail.


    See API documentation for guides and examples.'
  version: v1
servers:
- url: /v1
tags:
- name: Directory
  description: 'Directory reconciliation: propose and apply the company link that contacts created outside a transmittal send are missing.'
paths:
  /directory/contact-company-links:
    get:
      tags:
      - Directory
      summary: List proposed contact-to-company links
      description: 'List the contacts that have no company but whose email domain a company owns.


        Nothing is written. Each entry names the company that `POST` would link and,

        where a domain sits on more than one company, the ones that lost to it.


        A contact whose domain no company claims is not listed: there is nothing to

        propose. Archived contacts are excluded, and an archived company claims no

        domain.'
      operationId: external_list_contact_company_links_route_directory_contact_company_links_get
      security:
      - HTTPBearer: []
      parameters:
      - name: page
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          description: Page number (1-indexed).
          default: 1
          title: Page
        description: Page number (1-indexed).
      - name: page_size
        in: query
        required: false
        schema:
          type: integer
          maximum: 100
          minimum: 1
          default: 50
          title: Page Size
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactCompanyLinkListV1'
        '401':
          description: Unauthorized
          content:
            application/json:
              example:
                error: api_key_invalid
                message: Invalid API key
              schema:
                $ref: '#/components/schemas/ErrorV1'
        '422':
          description: Validation error
          content:
            application/json:
              example:
                error: validation_error
                message: 'body -> name: Field required'
              schema:
                $ref: '#/components/schemas/ErrorV1'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              example:
                error: rate_limit_exceeded
                message: Rate limit exceeded. Please try again later.
              schema:
                $ref: '#/components/schemas/ErrorV1'
        '500':
          description: Internal server error
          content:
            application/json:
              example:
                error: internal_error
                message: An internal error occurred
              schema:
                $ref: '#/components/schemas/ErrorV1'
    post:
      tags:
      - Directory
      summary: Apply proposed contact-to-company links
      description: 'Set the company on contacts that have none, from their email domain.


        Applies the proposal `GET /directory/contact-company-links` returns, or the

        part of it named by `contact_ids`. Read that first: a company carrying a

        consumer domain such as `gmail.com` claims every personal address in the

        organization, and this endpoint cannot tell that apart from a real firm.


        The proposal is recomputed here rather than carried over from the `GET`, so

        `contact_ids` chooses contacts, not companies: if the company that won a

        contested domain is archived in between, the runner-up wins this call. The

        `applied` list names the company each contact actually got, so compare it

        against what you reviewed.


        Keep the `applied` list the response returns. It names every contact this

        call gave a company to, and nothing else records which contacts had none

        beforehand — so it is what a bad run has to be reversed from.


        A contact that already has a company is never touched, whether it had one

        all along or gained one between the read and this call. Safe to repeat —

        a second call with nothing left to do links nothing.'
      operationId: external_apply_contact_company_links_route_directory_contact_company_links_post
      security:
      - HTTPBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactCompanyLinkApplyV1'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactCompanyLinkApplyResultV1'
        '401':
          description: Unauthorized
          content:
            application/json:
              example:
                error: api_key_invalid
                message: Invalid API key
              schema:
                $ref: '#/components/schemas/ErrorV1'
        '422':
          description: Validation error
          content:
            application/json:
              example:
                error: validation_error
                message: 'body -> name: Field required'
              schema:
                $ref: '#/components/schemas/ErrorV1'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              example:
                error: rate_limit_exceeded
                message: Rate limit exceeded. Please try again later.
              schema:
                $ref: '#/components/schemas/ErrorV1'
        '500':
          description: Internal server error
          content:
            application/json:
              example:
                error: internal_error
                message: An internal error occurred
              schema:
                $ref: '#/components/schemas/ErrorV1'
components:
  schemas:
    ContactCompanyLinkV1:
      properties:
        contact_id:
          type: string
          title: Contact Id
        primary_email:
          type: string
          title: Primary Email
        first_name:
          anyOf:
          - type: string
          - type: 'null'
          title: First Name
        last_name:
          anyOf:
          - type: string
          - type: 'null'
          title: Last Name
        domain:
          type: string
          title: Domain
          description: Domain of `primary_email`, lowercased.
        company:
          $ref: '#/components/schemas/CompanyRefV1'
          description: 'The company that would be linked: the oldest non-archived company listing `domain` in its email domains.'
        also_claiming:
          items:
            $ref: '#/components/schemas/CompanyRefV1'
          type: array
          title: Also Claiming
          description: Other non-archived companies listing `domain`, in the order they lost to `company`. Normally empty; when it is not, review before applying — the domain is on more than one company.
      type: object
      required:
      - contact_id
      - primary_email
      - first_name
      - last_name
      - domain
      - company
      - also_claiming
      title: ContactCompanyLinkV1
      description: One contact with no company, and the company its email domain points at.
    CompanyRefV1:
      properties:
        id:
          type: string
          title: Id
        name:
          type: string
          title: Name
      type: object
      required:
      - id
      - name
      title: CompanyRefV1
      description: A company named in a proposed link.
    AppliedLinkV1:
      properties:
        contact_id:
          type: string
          title: Contact Id
        company_id:
          type: string
          title: Company Id
      type: object
      required:
      - contact_id
      - company_id
      title: AppliedLinkV1
      description: One link this call wrote.
    ContactCompanyLinkListV1:
      properties:
        data:
          items:
            $ref: '#/components/schemas/ContactCompanyLinkV1'
          type: array
          title: Data
        total:
          type: integer
          title: Total
          description: Total matches across all pages, not just this page.
        page:
          type: integer
          title: Page
        page_size:
          type: integer
          title: Page Size
      type: object
      required:
      - data
      - total
      - page
      - page_size
      title: ContactCompanyLinkListV1
      description: Paginated list of proposed contact-to-company links.
    ContactCompanyLinkApplyV1:
      properties:
        contact_ids:
          anyOf:
          - items:
              type: string
              maxLength: 64
            type: array
            maxItems: 1000
          - type: 'null'
          title: Contact Ids
          description: 'Apply only the proposed links for these contacts. Omit to apply every one. Ids that are not currently proposed are ignored, so a list built from an earlier `GET` cannot link a contact whose company has since been set. The 1000-id ceiling bounds the request body, not the write: omitting the field still applies the whole proposal.'
      type: object
      title: ContactCompanyLinkApplyV1
      description: Which of the proposed links to write.
    ErrorCode:
      type: string
      enum:
      - api_key_missing
      - api_key_invalid_format
      - api_key_invalid
      - api_key_expired
      - bad_request
      - forbidden
      - not_found
      - method_not_allowed
      - conflict
      - validation_error
      - rate_limit_exceeded
      - internal_error
      - range_too_large
      - data_export_in_progress
      title: ErrorCode
      description: Error codes for external API v1.
    ContactCompanyLinkApplyResultV1:
      properties:
        applied:
          items:
            $ref: '#/components/schemas/AppliedLinkV1'
          type: array
          title: Applied
          description: 'Every link this call wrote, contact by contact. Keep it: it names the contacts that held no company before the call, and it is therefore the only way to reverse a run that linked the wrong company — Cogram cannot tell a firm''s domain from a consumer one.'
        linked:
          type: integer
          title: Linked
          description: Contacts given a company by this call.
        skipped:
          type: integer
          title: Skipped
          description: Proposed links this call did not write, because the contact gained a company between the read and the write. An existing company is never overwritten.
      type: object
      required:
      - applied
      - linked
      - skipped
      title: ContactCompanyLinkApplyResultV1
      description: What the write did.
    ErrorV1:
      properties:
        error:
          $ref: '#/components/schemas/ErrorCode'
          description: Stable machine-readable code. Branch on this.
        message:
          type: string
          title: Message
          description: Human-readable detail. Wording may change.
      type: object
      required:
      - error
      - message
      title: ErrorV1
      description: 'JSON body format for all API v1 error responses.


        This model controls the actual serialization of error responses:

        {"error": "not_found", "message": "Project ''xyz'' not found"}'
  securitySchemes:
    HTTPBearer:
      type: http
      description: Organization API key. Minted by admins in Organization Settings → Integrations → API Keys; shown once, may carry an expiry.
      scheme: bearer
      bearerFormat: Cogram organization API key