Skip to content
DevelopersOpen app ↗
Browse documentation
Linkwiz API · v1

Add profiles to a report

Validate your JSON, understand duplicates and restore previously removed people.

Send a JSON array of profiles

Profiles to add
{
  "profiles": [
    {
      "linkedin_url": "https://www.linkedin.com/in/alex-example/",
      "name": "Alex Example",
      "title": "Marketing Director"
    },
    {
      "linkedin_url": "https://www.linkedin.com/in/jordan-example/",
      "name": "Jordan Example"
    }
  ]
}

Each profile requires a personal HTTPS LinkedIn URL. Optional display fields are name, title and headline. Send 1–100 profiles per import, up to 1 MiB. Only these fields are accepted. Company pages are not personal profiles. LinkedIn host aliases, trailing slashes and identity casing are normalized before duplicate checks.

Validate the whole batch first

Add ?validation_only=true to the import endpoint. Invalid rows return 422 with one-based row numbers and field errors. A validation failure saves nothing and queues nothing. Successful validation reports would_add or would_restore. It does not reserve work; the commit rechecks the report and current profiles.

Validation response
{
  "data": {
    "validation_only": true,
    "valid": true,
    "counts": {
      "submitted": 2,
      "would_add": 1,
      "would_restore": 0,
      "already_present": 1,
      "duplicate_in_input": 0,
      "would_queue_profiles": 1
    },
    "rows": [
      {
        "row_number": 1,
        "status": "would_add"
      },
      {
        "row_number": 2,
        "status": "already_present"
      }
    ]
  },
  "request_id": "77777777-7777-4777-8777-777777777777"
}
Profile stateCommit outcomeScanning
Not in the reportaddedBoth person scan modes queued
Previously removed from this reportrestored, with previously_removed_profile_restored noteBoth modes queued; previous details/history preserved
Already active in this reportalready_presentNo new scans
Repeated later in this JSON batchduplicate_in_inputNo additional scans; first row takes precedence

Read the receipt

Saved import receipt
{
  "data": {
    "id": "11111111-1111-4111-8111-111111111111",
    "report_id": "22222222-2222-4222-8222-222222222222",
    "state": "completed",
    "counts": {
      "submitted": 2,
      "added": 1,
      "restored": 1,
      "already_present": 0,
      "duplicate_in_input": 0,
      "profiles_queued": 2
    },
    "scan_requests": [
      {
        "mode": "full_profile",
        "scan_run_id": "55555555-5555-4555-8555-555555555555",
        "status_at_commit": "queued",
        "jobs_created": 2,
        "jobs_coalesced": 0
      },
      {
        "mode": "activity",
        "scan_run_id": "66666666-6666-4666-8666-666666666666",
        "status_at_commit": "queued",
        "jobs_created": 2,
        "jobs_coalesced": 0
      }
    ],
    "rows": [
      {
        "row_number": 1,
        "status": "added",
        "profile_id": "33333333-3333-4333-8333-333333333333",
        "scan_requests": [
          {
            "scan_run_id": "55555555-5555-4555-8555-555555555555",
            "mode": "full_profile"
          },
          {
            "scan_run_id": "66666666-6666-4666-8666-666666666666",
            "mode": "activity"
          }
        ]
      },
      {
        "row_number": 2,
        "status": "restored",
        "profile_id": "44444444-4444-4444-8444-444444444444",
        "notes": [
          {
            "code": "previously_removed_profile_restored",
            "message": "This profile was previously removed from this report. It has been restored and queued for scanning."
          }
        ],
        "scan_requests": [
          {
            "scan_run_id": "55555555-5555-4555-8555-555555555555",
            "mode": "full_profile"
          },
          {
            "scan_run_id": "66666666-6666-4666-8666-666666666666",
            "mode": "activity"
          }
        ]
      }
    ],
    "created_at": "2026-09-11T12:00:00Z",
    "expires_at": "2026-10-11T12:00:00Z"
  },
  "request_id": "88888888-8888-4888-8888-888888888888"
}

Rows preserve input order. Receipt counts distinguish additions, restorations and skips. The receipt contains profile references and scan references, not a copy of submitted personal values. Its completed state confirms admission only.

Reports already being scanned

Imports work while scans or schedules are active. New work is coordinated with the queue; existing schedules and unrelated running jobs remain intact. Imports do not rescan the company page. An archived report returns 409. Adding an active duplicate does not retry its failed scans; use the existing product workflow for scan operations.