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

# Imports one batch of a file (a header and at most 1,000 rows) into an import


> lead source. Every row is written as history: dated by the file's own submission time or default\_submitted\_at, never alerted on, billed or followed up until somebody starts it. A row already imported is not written again. dry\_run previews the batch. REST only, like the declaration.




## OpenAPI

````yaml /api/openapi.json post /v1/provider-lead-sources/import
openapi: 3.0.0
info:
  title: Erdo API
  description: >-
    Erdo's REST API: query and write datasets, run agents, manage threads,
    integrations, pages, evals, workstreams, experiments, and bounded outreach.
    Authenticate with a Bearer API key (erdo_api_...) or scoped token
    (erdo_token_...).
  version: '2026-11-02'
servers:
  - url: https://api.erdo.ai
    description: Production
security:
  - bearerAuth: []
paths:
  /v1/provider-lead-sources/import:
    post:
      summary: >
        Imports one batch of a file (a header and at most 1,000 rows) into an
        import
      description: >
        lead source. Every row is written as history: dated by the file's own
        submission time or default\_submitted\_at, never alerted on, billed or
        followed up until somebody starts it. A row already imported is not
        written again. dry\_run previews the batch. REST only, like the
        declaration.
      operationId: POST:mcp.ImportLeadSourceRowsAPI
      requestBody:
        content:
          application/json:
            schema:
              properties:
                default_submitted_at:
                  description: >
                    of their own, when the mapping has none or a row's is blank.
                    A file of contacts with no dates still needs one: history
                    keeps each lead's own arrival, and Erdo never invents it.
                  title: >
                    default_submitted_at (RFC 3339) dates rows that carry no
                    submission time
                  type: string
                dry_run:
                  title: >
                    dry_run maps the rows and counts what would be written,
                    writing nothing.
                  type: boolean
                header:
                  items:
                    type: string
                  title: |
                    header is the file's header row.
                  type: array
                name:
                  title: |
                    name is the import source's name.
                  type: string
                rows:
                  items:
                    items:
                      type: string
                    type: array
                  title: >
                    rows are the file's rows, one string per cell, at most 1,000
                    a request.
                  type: array
              type: object
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  already_written:
                    format: int64
                    title: >
                      already_written is how many earlier imports or reads
                      already wrote.
                    type: integer
                  created:
                    format: int64
                    title: |
                      created is how many leads new to the dataset were written.
                    type: integer
                  created_leads:
                    description: >
                      to start follow-up on. It includes leads an earlier
                      request with the same rows created, so a batch sent again
                      after a failure still names every one.
                    items:
                      type: string
                    title: >
                      created_leads are the permanent ids of the leads this
                      batch's rows created,
                    type: array
                  existing:
                    format: int64
                    title: >
                      existing is how many matched a lead the dataset already
                      has.
                    type: integer
                  no_contact:
                    format: int64
                    title: |
                      no_contact is how many have neither an email nor a phone.
                    type: integer
                  preview:
                    $ref: '#/components/schemas/eventpipeline.LeadSourcePreview'
                  refused:
                    description: |
                      more than one lead.
                    format: int64
                    title: >
                      refused is how many were held for review: contact details
                      that point at
                    type: integer
                  unreadable:
                    format: int64
                    title: >
                      unreadable is how many the mapping cannot read (no id, no
                      readable time).
                    type: integer
                type: object
          description: Success response
        default:
          $ref: '#/components/responses/APIError'
components:
  schemas:
    eventpipeline.LeadSourcePreview:
      properties:
        already_written:
          format: int64
          title: |
            already_written is how many the ledger has already dealt with.
          type: integer
        existing_columns:
          description: |
            a surface can say a suggestion matches one.
          items:
            type: string
          title: >
            existing_columns are the lead dataset's own columns a source may
            write, so
          type: array
        format_columns:
          additionalProperties:
            type: string
          description: >
            one lead column each is read as when it is read: Meta's
            company\_name as company, campaign\_name as ad\_campaign\_name. A
            surface offers such a field only that column or nothing.
          title: >
            format_columns are the fields the format itself knows, by field, and
            the
          type: object
        header:
          description: |
            body's keys.
          items:
            type: string
          title: >
            header is the fields the source offers: a sheet's header row, a
            sample
          type: array
        history:
          description: >
            before the source was declared. No alert, no follow-up until
            started.
          format: int64
          title: >
            history is how many would be written as history: leads who got in
            touch
          type: integer
        missing_fields:
          items:
            type: string
          title: |
            missing_fields are fields the mapping needs and the header lacks.
          type: array
        new:
          format: int64
          title: |
            new is how many would be written as leads getting in touch now.
          type: integer
        not_read:
          items:
            type: string
          title: >
            not_read are the fields the mapping leaves out, which are never
            written.
          type: array
        read_columns:
          additionalProperties:
            type: string
          description: >
            column each becomes: what was named in columns and what the format
            reads by itself (Meta's company\_name as company), so a person sees
            every field a lead gets from the source.
          title: >
            read_columns are the fields the mapping reads, by field, and the
            lead
          type: object
        rows:
          format: int64
          title: |
            rows is how many rows the source holds now.
          type: integer
        sample:
          items:
            type: object
          title: |
            sample is the first rows as they would be written.
          type: array
        skipped:
          additionalProperties:
            format: int64
            type: integer
          title: |
            skipped counts rows that would not be written, by reason.
          type: object
        suggested_columns:
          additionalProperties:
            type: string
          description: |
            person to confirm.
          title: >
            suggested_columns proposes a lead column for each field not read,
            for a
          type: object
        suggested_values:
          additionalProperties:
            additionalProperties:
              type: string
            type: object
          description: >
            answers, the value each answer is stored as in its lead column, by
            field then answer: "are\_you\_a\_broker?" {"Yes, I'm an agent":
            "true"}. Saved as the mapping's values once a person confirms them.
          title: |
            suggested_values proposes, for a field holding a small fixed set of
          type: object
        test:
          format: int64
          title: |
            test is how many the source marks as test submissions.
          type: integer
      title: |
        LeadSourcePreview is a dry run's account of what a source would write.
      type: object
  responses:
    APIError:
      content:
        application/json:
          schema:
            externalDocs:
              url: https://pkg.go.dev/encore.dev/beta/errs#Error
            properties:
              code:
                description: Error code
                example: not_found
                externalDocs:
                  url: https://pkg.go.dev/encore.dev/beta/errs#ErrCode
                type: string
              details:
                description: Error details
                type: object
              message:
                description: Error message
                type: string
            title: APIError
            type: object
      description: Error response
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An Erdo API key (erdo_api_...) or scoped token (erdo_token_...).

````

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