Play Video
zapier logo

Oppora in Zapier

Use Zapier's built-in 'Webhooks by Zapier' action to call Oppora from any of Zapier's 7,000+ apps. No custom Zapier app required — just paste URL, headers, and body.

Before you start

  • 1An Oppora API key (Integrations → Oppora API in the app). Starts with opp_live_…
  • 2A paid Oppora plan (Pro or Max). API keys aren't available on Free.
  • 3A Zapier plan that includes Premium apps — "Webhooks by Zapier" is a premium app, so Free Zapier plans can't use it.

Set up Webhooks by Zapier

Zapier doesn't have a native Oppora app, so we use the built-in Webhooks by Zapier action with Custom Request. Bearer auth lives in the headers field — pasted once per Zap step.

  1. In your Zap, add an action step → search Webhooks by Zapier.
  2. Pick the action event: Custom Request (the most flexible — lets you set method, headers, and body separately).
  3. Configure the action:
    Webhooks by Zapier — Custom Request
    Method:        POST
    URL:           [set per recipe below]
    Data Pass-Through? No
    Data:          [set per recipe below — leave blank if using Body]
    Headers:
      Authorization | Bearer YOUR_KEY
      Content-Type  | application/json
    Wrap Request In Array? No
    File:           (leave blank)
    Unflatten:      No
  4. Use the Test action button to fire one real call and confirm the response. Zapier shows every field of the JSON response so you can map them downstream.

Tip: save the configured step as a Zap template — copying the step into other Zaps avoids re-pasting the bearer.

Recipes

Each recipe is one Webhooks by Zapier → Custom Request action. Map trigger fields into the body via Zapier's field-picker (no manual template syntax — just click the field in the dropdown).

POST /email/search

Find email by name + domain

Resolves a verified work email when you have a person's name and their company's website domain.

Request body
{
  "first_name": "Alice",
  "last_name": "Chen",
  "domain": "stripe.com"
}
Response
{
  "email": "[email protected]",
  "status": "valid",
  "source": "oppora",
  "credit_charged": 1,
  "credits_remaining": 4823
}
  • `domain` is required — free-text company names are not accepted (they cause wrong-company matches).
  • Credit is charged only when an email is returned with status `valid` or `risky`. Misses are free.
Wire it in Zapier

URL: https://api.oppora.ai/api/v1/public/email/search. In the Data field, paste this and use Zapier's field-picker to insert each value:

Data (JSON)
{
  "first_name": "{{first_name}}",
  "last_name":  "{{last_name}}",
  "domain":     "{{domain}}"
}

Replace each {{ field }} with the actual mapped field from your trigger using Zapier's picker. After running, you'll see email and status available as output fields for downstream steps.

POST /email/verify

Verify an email

Check deliverability before sending. Use `mode: "advanced"` for catch-all domains where `standard` returns `risky` or `unknown`.

Request body
{
  "email": "[email protected]",
  "mode": "standard"
}
Response
{
  "email": "[email protected]",
  "mode": "standard",
  "status": "valid",
  "credit_charged": 1,
  "credits_remaining": 4822
}
  • `mode` is `standard` (fast) or `advanced` (deep SMTP, catch-all aware). Both charge on result.
Wire it in Zapier

Add a Filter by Zapier step after email-search: Only continue if status = valid OR risky. For risky rows, add a second verify step with "mode": "advanced".

Data (JSON)
{
  "email": "{{email}}",
  "mode":  "standard"
}
POST /phone/search

Lookup phone from LinkedIn URL

Best with a LinkedIn URL. Falls back to (name + company) or (name + domain). DB-cache hits are free; external provider hits charge 1 phone credit on success.

Request body
{
  "linkedin_url": "https://www.linkedin.com/in/alice-chen-vp"
}
Response
{
  "phone": "+14155551234",
  "status": "valid",
  "source": "oppora_db",
  "credit_charged": 0,
  "credits_remaining": 1200
}
  • `source: "oppora_db"` = pulled from cache (free). External provider sources (wiza, dropcontact, etc.) charge 1 credit per resolved phone.
Wire it in Zapier

LinkedIn URL gives the highest hit rate. If your trigger doesn't always supply one, split into two Paths (Zapier's branching) — one uses linkedin_url, the other uses name + domain.

Data — LinkedIn URL path
{
  "linkedin_url": "{{linkedin_url}}"
}
Data — name + domain path
{
  "first_name": "{{first_name}}",
  "last_name":  "{{last_name}}",
  "domain":     "{{domain}}"
}
POST /discover/companies

Discover companies matching ICP filters

Search the global company DB by industry, size, location, revenue, funding, growth. Returns up to 100 rows per page with cursor pagination. Every row carries an Oppora `id` so you can chain into add-to-list flows.

Request body
{
  "industry": ["Software Development"],
  "hq_country": "USA",
  "size": ["51-200", "201-500"],
  "revenue_range_min": 5000000,
  "limit": 25
}
Response
{
  "data": [
    {
      "id": 8421,
      "name": "Stripe",
      "domain": "stripe.com",
      "industry": "Financial Services",
      "size": "5001-10000",
      "employee_count": 8200,
      "year_founded": 2010,
      "total_funding_usd": 8700000000,
      "country": "USA"
    }
  ],
  "count": 25,
  "total": 1842,
  "next_cursor": "eyJjdXJzb3IiOiIuLi4ifQ",
  "has_more": true,
  "credit_charged": 1,
  "credits_remaining": 4821
}
  • Resolve exact filter values via `GET /filters/industries` and `GET /filters/countries` first — wrong strings match zero rows.
  • `hq_country` is a single ISO 3-alpha code ("USA", "GBR", "IND").
Wire it in Zapier

Discovery typically returns dozens of rows per call — use Zapier's Looping by Zapier action to iterate over data[], then feed each row into a downstream step (e.g. create a row in Google Sheets).

Data — first page
{
  "industry": ["Software Development"],
  "hq_country": "USA",
  "size": ["51-200", "201-500"],
  "limit": 100
}

For multi-page runs: store next_cursor in a Storage by Zapier value and re-trigger the Zap until has_more = false.

POST /discover/people

Discover people by title, department, company

Search the global people DB by title, department, management level, company, industry, skills, location, years of experience. Returns the same row shape your AI/list tools expect.

Request body
{
  "title": ["VP Sales", "Head of Sales"],
  "departments": ["Sales"],
  "management_levels": ["VP", "Director"],
  "company_name": ["Stripe", "Plaid"],
  "years_experience": ["6 to 10 years", "More than 10 years"],
  "limit": 25
}
Response
{
  "data": [
    {
      "id": 42818,
      "first_name": "Alice",
      "last_name": "Chen",
      "full_name": "Alice Chen",
      "title": "VP of Sales",
      "department": "Sales",
      "management_level": "VP",
      "linkedin_url": "https://www.linkedin.com/in/alice-chen-vp",
      "location": "San Francisco",
      "years_experience": "More than 10 years",
      "company": {
        "id": 8421,
        "name": "Stripe",
        "domain": "stripe.com"
      }
    }
  ],
  "count": 25,
  "total": 412,
  "next_cursor": "eyJjdXJzb3IiOiIuLi4ifQ",
  "has_more": true,
  "credit_charged": 1,
  "credits_remaining": 4820
}
  • Resolve exact `departments` and `management_levels` values via `GET /filters/departments` and `GET /filters/management-levels` first.
  • `years_experience` must use the exact bucket labels: "Less than 1 year", "1 to 2 years", "3 to 5 years", "6 to 10 years", "More than 10 years".
  • No email or phone in the response — chain into `/email/search` or `/phone/search` for that.
Wire it in Zapier

Pair with Looping by Zapier for per-company lookups: each iteration calls this with one company from the upstream list. Map data[].first_name / .linkedin_url to downstream steps.

Data — per-company decision-makers
{
  "title": ["VP Sales", "Head of Sales"],
  "departments": ["Sales"],
  "management_levels": ["VP", "Director"],
  "company_name": ["{{company_name}}"],
  "limit": 10
}

Need more endpoints?

The recipes above are the most common flows — Oppora exposes 17 REST endpoints in total (discovery, bulk async jobs, filter helpers, account info). See the full REST API reference for the complete surface.