Skip to content

Connect IvaBoard to your product.Plain HTTPS, signed and scoped.

Sign your customers in from your own app, post and vote for them from your server, read public data and receive signed webhooks. Every key belongs to one product and does one job.

A ticket call from your backend, with sample values

# 201. The ticket works once and expires in 60 seconds.
POST /api/v1/integrations/<publicProductKey>/tickets
Authorization: Bearer $IVABOARD_HANDOFF_KEY
302 Location: redeemUrl

Sign-in handoff: customers vote without a new password.

Your backend vouches for the signed-in customer with a one-time ticket. The browser carries it back, and the portal redeems it.

  1. The portal sends the browser to your sign-in URL

    You save one https sign-in URL in the console. The portal adds a one-time state value to it.

  2. Your backend asks for a ticket

    Once the user is signed in to your app, your server calls the tickets endpoint with your handoff key, the state and your own user id.

  3. Redirect the browser to the redeem URL

    The portal redeems the ticket and the customer is signed in. No second password, no email loop.

Ticket
60 seconds, single use. Mint it and redirect at once.
Flow
600 seconds for the round trip through your product.
Session
24 hours, then the customer presses Continue again.

When someone leaves your product, call the sessions revoke endpoint with their user id and their IvaBoard sessions end.

Mint a ticket, with sample values

# Your backend, after the customer signs in to your app.
POST /api/v1/integrations/<publicProductKey>/tickets
Authorization: Bearer $IVABOARD_HANDOFF_KEY
Content-Type: application/json
{
  "state": "<the state the portal sent you>",
  "externalUserId": "user_4821",
  "displayName": "Dana Whitfield"
}
# 201 with the redeem URL and when it expires. Check that it starts with your portal origin.
{
  "redeemUrl": "https://ideas.acme.com/p/<publicProductKey>/handoff/return?state=...&ticket=...",
  "expiresAt": "2026-10-15T12:00:00.000Z"
}
# Answer the browser with a redirect. Do not log or show the URL.
302 Location: redeemUrl

Sample values. The user id is yours and is the identity. Email is stored only if you turn on Trust email addresses.

Write API: post and vote for your users.

A feedback box inside your app, or an "I want this too" button beside a feature. The calls come from your server, for a user who is signed in to your product.

  • The idea or vote appears under your user, as if they pressed the button on the portal.
  • An Idempotency-Key on every post means a retry within 24 hours returns the same idea.
  • 60 calls a minute per key. Each member keeps the portal's own limits, such as 5 ideas an hour.
  • Server only. Your user id travels in the request body, never in the URL.

Post an idea and cast a vote for a signed-in user

# Post an idea. Sample values.
POST /api/v1/public/<publicProductKey>/posts
Authorization: Bearer $IVABOARD_WRITE_KEY
Idempotency-Key: 7c1f6b0e-2d4a-4d51-9a53-0e3f2b8c9a10
{
  "boardSlug": "ideas",
  "title": "Scheduled reports by email",
  "member": { "externalUserId": "user_4821" }
}
# Cast and withdraw that member's one vote. The member goes in the body.
PUT /api/v1/public/<publicProductKey>/posts/<postId>/vote
DELETE /api/v1/public/<publicProductKey>/posts/<postId>/vote

Needs a write key and sign-in from your product to be set up. Votes are idempotent by their method.

Public read API: your roadmap on your own pages.

Show ideas and votes inside your product or your website, from data you do not have to copy.

  • You get what an anonymous visitor of the portal sees: approved ideas on public boards.
  • No authors, voters, followers or internal notes, ever.
  • Filter by board or status. 600 requests a minute per key.
  • A refused request always answers the same way, so a key tells nobody anything about other products.

Read a product's public ideas

# Newest first, one page at a time. Sample values.
curl -H "Authorization: Bearer $IVABOARD_READ_KEY" \
  "https://app.ivaboard.com/api/v1/public/<publicProductKey>/posts?limit=20&status=planned"
# Each item: id, slug, title, bodyHtml, boardSlug, status, voteCount, commentCount, createdAt, updatedAt.
# The answer carries nextCursor for the next page.

The key goes in a header, never in the URL.

Scoped API keys, with rotation.

Each key has one scope and one product, so a leaked key can do one small thing.

read

Reads the public ideas of one product. Nothing else.

write

Posts ideas and casts or withdraws votes for your users. Reads nothing.

handoff

Mints sign-in tickets and revokes sessions. Reads and writes nothing else.

Shown once
IvaBoard keeps only a hash. A lost key cannot be recovered, so mint a new one.
One product
A key works for the product it was minted on and no other.
Rotation
Rotate to a successor with the same scope. The old key keeps working for a window you choose, from 60 seconds to 7 days.
Revoke
A leaked key is revoked, not rotated. It stops on its next request.
Who can mint
Workspace owners and admins only.

Signed webhooks you can verify.

Each delivery is signed with HMAC-SHA256 over the timestamp and the raw body. Check the signature before you trust the call.

Events

post.created
An idea is first published. Not sent for imports, API-created or staff-on-behalf ideas.
post.status_changed
An idea changes status, when the portal shows that change.
comment.created
A public comment or reply is posted.
changelog.published
A changelog entry is published, with or without linked ideas.

Headers on every request

x-fh-timestamp
When it was sent, in Unix seconds.
x-fh-signature
v1= then the hex HMAC-SHA256 of the timestamp, a dot and the raw body. Two v1 values while a secret is rotating.
x-fh-event-id
The event id. The same on every retry, so dedupe on it.

Only what the public portal shows is sent. Nothing for private boards, hidden ideas or internal notes. HTTPS only, up to 10 webhooks per product, retried five times, and the delivery log is kept for 90 days.

A delivery to your endpoint, with sample values

POST /webhooks/ivaboard
x-fh-timestamp: 1760520600
x-fh-signature: v1=<hex HMAC-SHA256 of timestamp + "." + raw body>
x-fh-event-id: evt_sample_8f3a
{
  "id": "evt_sample_8f3a",
  "type": "post.status_changed",
  "occurredAt": "2026-10-15T09:30:00.000Z",
  "product": { "publicKey": "pk_sample" },
  "data": { "title": "Dark mode for the dashboard", "voteCount": 128 }
}

Answer any 2xx to acknowledge. A redirect is never followed.

Embeds that need no JavaScript.

Drop the roadmap or changelog into a page you already have.

  • Three embeds: the roadmap, the changelog and one changelog entry.
  • Only the websites you list in the console can frame them.
  • They use your accent colour and follow the visitor's light or dark setting.

Embed the roadmap or the changelog, with sample values

<iframe
  src="https://<your portal address>/embed/<publicProductKey>/roadmap"
  title="Product roadmap"></iframe>
<!-- Also: /embed/<publicProductKey>/changelog and /embed/<publicProductKey>/changelog/<entry> -->

Read-only pages in an iframe. No script to load.

Developer questions, answered plainly.

  • Which plans include the API and webhooks?

    All of them. The sign-in handoff, write and read APIs, signed webhooks and embeds are included in every annual and lifetime plan.

  • Do you have SDKs or ready-made integrations?

    No. IvaBoard offers plain HTTPS APIs, signed webhooks and embeds. You can call them from any language without a client library.

  • Can I call the write API from a browser?

    No. Keys are for servers. A request that carries a browser cookie next to a key is refused, so a key never ends up in front-end code.

  • What happens if my webhook endpoint is down?

    IvaBoard retries a failed delivery up to five more times, starting at 30 seconds and doubling each time. Every retry carries the same event id, so you can ignore repeats.

Connect your product to your customers' ideas.

Pick a plan, and we set up your workspace within one business day. Questions about the API? Write to support@ivaboard.com.