Skip to main content
The PickFu v2 API is a greenfield surface mounted at https://api.pickfu.com/v2, alongside the existing v0/v1 API. It is designed for partners integrating PickFu into their own products — drafting a survey, funding it, publishing it, and reading the results — end-to-end, without ever loading app.pickfu.com. v2 keeps the same team, same account, same billing, and the same pricing as the PickFu app. It is a new contract, not a new product.
If you’re already using v1 (/v1), you don’t need to switch. v0, v1, and v2 run side-by-side on the same production API. Pick v2 when you want the ergonomics below; stay on v1 if it’s already working for you.

Base URLs

The machine-readable OpenAPI 3.1 contract is served unauthenticated at GET /v2/openapi.json. Point client generators (Stripe-style SDKs, Postman, openapi-typescript) at that URL.

What’s in v2

Me

GET /v2/me — the calling key, its scopes, and the team it acts for.

Surveys

Draft, edit, read, list, and stop surveys. Every read includes a cost quote.

Media

POST /v2/media — host images and videos on the PickFu CDN.

Traits

GET /v2/traits — audience traits available per respondent country.

Billing

Credit balance, credit packs bought on Stripe Checkout, saved cards via the Stripe Billing Portal.

Publish + pay

POST /v2/surveys/{id}/publish — one call that pays for and publishes a draft.

Results

Cursor-paged responses and a synchronous CSV export.

Webhooks

Signed survey.completed and order.paid deliveries.

How v2 differs from v1

v2 is a different resource shape from v1. It is not a drop-in upgrade — resource IDs, error envelopes, and pagination shapes are all different by design. Choose one surface per integration.

Canonical PickFu IDs

Every v2 resource identifies itself with a canonical, prefixed PickFu ID: v2 never accepts or emits legacy GUIDs as resource IDs. The browser results page URL is unchanged and continues to use the survey’s GUID; that’s a browser URL, not a v2 identifier.

Scoped API keys

v2 accepts API keys only (sk_live_…). OAuth tokens are v1-only. Keys carry explicit scopes: read, write, and/or spend. A key with no scopes is rejected with 403 api_key_unscoped — there is no implicit “god mode” any more. See Authentication.

Stripe-shaped error envelope

Every non-2xx response — validation, 404, 429, unknown route — uses the same envelope:
requestId is also returned as X-Request-Id. Quote it when you file a support ticket. See Errors.

Cursor pagination

List endpoints return { data, hasMore, nextCursor }. There are no offsets and no totals. Pass nextCursor back as ?cursor=… to fetch the next page. See Pagination.

Idempotency

POST /v2/orders and POST /v2/surveys/{id}/publish require an Idempotency-Key header. Retrying with the same key and body replays the original 2xx response for 24 hours. See Idempotency.

Webhook signing

Every delivery is a { id, type, createdAt, data: { object } } envelope signed with X-PickFu-Signature: t=<unix-seconds>,v1=<hex-hmac>. See Webhooks.

The publish flow

The single interesting workflow in v2 is draft → quote → publish → results. Everything else supports it.
1

Create a draft

POST /v2/surveys returns a draft survey (status: "unpublished") with a cost quote and the team’s current creditBalance. Nothing is charged yet.
2

Read or refresh the quote

GET /v2/surveys/{id} and PATCH /v2/surveys/{id} both return a fresh cost quote. The most recent quote is what publish will honour.
3

Publish

POST /v2/surveys/{id}/publish charges the quote — credits first (oldest expiry first), then any shortfall to the team’s default saved card. 200 means paid, not yet live.If the quote has changed since your last read, publish answers 409 quote_changed and doesn’t charge anything. If there’s a shortfall and no saved card, it answers 402 insufficient_credits with the smallest pack that would cover it.
4

Wait for completion

Poll GET /v2/surveys/{id} (status moves in-progress → completed) or listen for the survey.completed webhook. Then read GET /v2/surveys/{id}/responses or download GET /v2/surveys/{id}/exports/csv.
The publishing and payments page walks through funding, 402 recovery, and the Stripe Billing Portal.

Next steps

Authentication

Mint a key, choose scopes, and identify your team.

Errors

The { error, requestId } envelope and per-status guidance.

Rate limits

Per-team limits and how to back off on 429.

Pagination

Cursor pagination for every list endpoint.

Idempotency

Safe retries for order creation and publish.

Publishing and payments

Quotes, credits, saved cards, credit packs, and the Billing Portal.

Webhooks

Endpoints, signing, and the survey.completed / order.paid events.