Skip to main content
POST
/
api
/
network
/
enrich
Enrich network connections
curl --request POST \
  --url https://app.puffle.ai/api/network/enrich \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "connectionIds": [
    "3c90c3cc-0d44-4b50-8888-8dd25736052a"
  ],
  "confirm": true
}
'
{ "preview": true, "count": 3, "estimatedCost": 0.012, "connections": [ { "connectionId": "cc111111-1111-1111-1111-111111111111", "firstName": "Ada", "lastName": "Lovelace", "linkedinUrl": "https://www.linkedin.com/in/ada" } ], "creditsRequired": 3, "creditBalance": 500, "creditsSufficient": true }

Overview

Call twice. First pass (confirm omitted or false) returns a preview with the filtered count (rows without linkedin_url and already-enriched rows are stripped), the estimated USD cost at the Apify rate, and credit affordability. Second pass (confirm: true) actually runs the scraper. On execute:
  1. Server re-checks credit balance. Returns 402 if insufficient.
  2. Calls the harvestapi~linkedin-profile-scraper Apify actor with the filtered LinkedIn URLs.
  3. For each success: updates network_connections with enriched fields, deletes existing rows in network_connection_experience / _education / _details, then re-inserts the fresh mapped rows.
  4. For each failure: writes enrichment_error onto the connection row. No credits charged for failures.
  5. Charges credits for successCount at the end.

AI agent notes

Two-call contract is load-bearing. Do not skip the preview — the execute path is synchronous, charges credits, and can’t be undone. Always show the user count, estimatedCost, and creditsSufficient before calling with confirm: true.Partial failure is normal. The response’s successCount and failureCount will often be non-zero together — scraper misses, deactivated profiles, etc. Surface per-row results[].error to the user rather than treating the whole call as a failure.Idempotency. Already-enriched rows (enriched_at IS NOT NULL) are filtered out server-side. Re-submitting the same connectionIds is a safe no-op once they’re enriched.Cost. $4 per 1000 profiles at Apify’s current rate, plus one credit per successful profile. Show both numbers to the user before confirming.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json

Enrichment request. Two modes: confirm: false (or omitted) = preview; confirm: true = execute.

connectionIds
string<uuid>[]
required

Ids of network_connections rows to enrich. Rows without a linkedin_url or already enriched are filtered out server-side.

Minimum array length: 1
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
confirm
boolean

Dry-run flag. When omitted or false, returns a preview with cost/credit estimate and does not enrich. When true, actually runs the Apify scraper and charges credits for each success.

Response

Preview or execute payload, discriminated by preview. Execute may include partial failures in results[].error with non-zero failureCount.

Discriminated by the preview field. Preview includes credit info; execute includes per-row results.

preview
enum<boolean>
required
Available options:
true
count
integer
required
Required range: 0 <= x <= 9007199254740991
estimatedCost
number
required

USD cost at the Apify pay-per-result rate ($4 per 1000 profiles).

connections
object[]
required
creditsRequired
integer
required
Required range: 0 <= x <= 9007199254740991
creditBalance
integer
required
Required range: 0 <= x <= 9007199254740991
creditsSufficient
boolean
required