Skip to main content

Quickstart

This walk mints a key, reads your own flows, and pushes one submission in. It takes about five minutes.

1. Get a key​

Open your organisation's settings and go to API (/app/settings/api). Start a new key, choose "Only select permissions...", and turn on Responses (read) and Flows (read). That is everything this walk needs. The secret is shown once, so copy it before you close the dialog.

2. Keep it out of your shell​

A key typed on the command line lands in your shell history and in ps output for other users on the machine. Put it in a curl config file instead:

umask 077
cat > ~/.hop-api.conf <<'EOF'
header = "Authorization: Bearer hop_sk_..."
EOF
export HOP_BASE=https://stage-api.hopforms.com

This walk runs against stage, a separate database with its own keys, so nothing here touches real data. Switch to https://api.hopforms.com for production once you are ready.

Every example below passes --config ~/.hop-api.conf. Never add -L to these calls; the Authentication guide says why.

3. Who am I​

curl -sS -i --config ~/.hop-api.conf "$HOP_BASE/v1/me"

The answer names your organisation and the scopes this key holds, so you can confirm the key you pasted is the one you meant to mint. -i prints the response headers along with the body; check RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, which are on every response the API answers and tell you how much room this key has left before you build anything that depends on it.

4. Your flows​

curl -sS --config ~/.hop-api.conf "$HOP_BASE/v1/flows?limit=100"

The answer is an envelope, {"data": [...], "next_cursor": ..., "has_more": ...}. Pick a flow_id from data for the next two steps. If has_more is true, there are more flows than this one page; the pagination recipe on the overview page covers reading all of them.

5. One flow's submissions​

curl -sS --config ~/.hop-api.conf \
"$HOP_BASE/v1/flows/{flow_id}/submissions?limit=100"

Take the next_cursor from that answer and pass it back to read the next page:

curl -sS --config ~/.hop-api.conf \
"$HOP_BASE/v1/flows/{flow_id}/submissions?limit=100&after={cursor}"

For a job that runs on a schedule, such as a nightly pull, add updated_since on the first run, then keep the last next_cursor and resume from it on the next run; the overview's pagination section says why a cursor beats a timestamp here:

curl -sS --config ~/.hop-api.conf \
"$HOP_BASE/v1/flows/{flow_id}/submissions?updated_since=2026-09-01T00:00:00Z"

6. The same list, as CSV​

Add ?format=csv and the same path answers with a CSV file instead of a JSON page. Drop limit when you do: the export is unpaginated, and limit together with format=csv is a 400.

curl -sS --config ~/.hop-api.conf \
"$HOP_BASE/v1/flows/{flow_id}/submissions?format=csv" -o submissions.csv

7. Push a submission in​

Writing needs the submissions:write scope, which the key from step 1 does not hold. Add it from the API settings screen, or mint a second key for this step.

answers keys must be fields of the flow's current published version. List them first:

curl -sS --config ~/.hop-api.conf "$HOP_BASE/v1/flows/{flow_id}/schema"

Use a field name from that schema in place of reading below, which is only this walk's example.

curl -sS --config ~/.hop-api.conf -X POST \
-H "Idempotency-Key: import-row-841" -H "Content-Type: application/json" \
"$HOP_BASE/v1/flows/{flow_id}/submissions" \
-d '{"answers": {"reading": "4.1"}}'

This creates a real submission on whichever base you set in step 2, stage or production. Idempotency-Key is required on this endpoint. The first call answers 201. Run the exact same request again, same key and same body, and you get the same 201 payload back as a 200 with Idempotent-Replayed: true, and nothing is created twice.

8. Where to next​

Read Authentication for scopes, refusals and rate limits in full. Read Errors for the error shape and every code. Browse the reference for a runnable example of every endpoint in curl, Python and Node.