Skip to main content

Getting started with the PublicInput Core API

Authenticate with OAuth2 client credentials and use the Core API to read meetings, agendas, sections, and items.

Written by Jay Dawkins

Overview

The PublicInput Core API is a modern REST API for reading and managing meeting and agenda data programmatically. It uses OAuth2 client-credentials authentication and returns short-lived JWT access tokens.

This is separate from the legacy API-key integration used by Zapier. The Core API is the recommended interface for new server-to-server integrations.

  • Content type: application/json

  • Authentication: OAuth2 client credentials → JWT bearer token

  • Token lifetime: 30 minutes

Before you begin

You will need an API Client (a client ID and client secret) and your Tenant ID. Both come from your PublicInput admin settings.

Create an API Client

API access is a plan feature. If you do not see the section below, ask your account team to enable API access for your organization.

  1. In the PublicInput admin, click the Settings gear icon in the main navigation, open the Integrations tab, and scroll to the API Clients section. (This is separate from the "API Access" keys just above it, which are for the legacy API.)

  2. Click Create, give the client a name, and choose an access levelAdministrator, Publisher, Editor, or DataCollector. The access level controls what the credentials can do, mirroring the permission a teammate would have.

  3. The client ID and client secret are shown once, at creation time. Copy the secret immediately and store it securely — it cannot be retrieved again. If it is lost or exposed, delete the client and create a new one.

Creating and managing API Clients requires Administrator permission on your organization.

Find your Tenant ID

Your Tenant ID is your PublicInput organization (customer) ID. It is sent on every request in the X-Tenant-ID header. If you are unsure of the value, your account admin can confirm it.

Keep your client secret confidential. Treat it like a password and never embed it in browser or mobile client code.

Step 1 — Get an access token

Exchange your client credentials for a JWT access token. Tokens expire after 30 minutes, so request a fresh one when needed (or cache and reuse until it nears expiry).

Request

POST https://apicore.publicinput.com/api/v1/auth/tokenContent-Type: application/json{  "grant_type": "client_credentials",  "client_id": "YOUR_CLIENT_ID",  "client_secret": "YOUR_CLIENT_SECRET"}

Response contains the JWT access token to use on subsequent calls.

{  "access_token": "eyJhbGciOiJ...",  "token_type": "Bearer",  "expires_in": 1800}

Step 2 — Make an authenticated request

Every protected endpoint requires two headers:

  • Authorization: Bearer <access_token>

  • X-Tenant-ID: <your-tenant-id>

Example — list the meetings for a project:

GET https://apicore.publicinput.com/api/v1/projects/123/meetingsAuthorization: Bearer eyJhbGciOiJ...X-Tenant-ID: your-tenant-id

Full cURL example:

curl https://apicore.publicinput.com/api/v1/projects/123/meetings \  -H "Authorization: Bearer $TOKEN" \  -H "X-Tenant-ID: your-tenant-id"

Response format

Responses are wrapped in a consistent envelope. The requested data is in data; success indicates the outcome, and message / errors carry detail when something goes wrong.

{  "success": true,  "message": null,  "data": { ... },  "errors": null,  "traceId": "00-abc123..."}

Include the traceId when reporting an issue to support — it lets us locate the exact request in our logs.

Pagination

List endpoints that can return many results accept Page and PageSize query parameters and return a paged envelope with the total count and the current page of items. For example:

GET /api/v1/projects/123/meetings?Page=1&PageSize=25

Available endpoints

Meetings

  • GET /api/v1/projects/{projectId}/meetings — Paginated list of meetings for a project. Supports SortField, SortDirection, Timeframe, Page, PageSize.

  • GET /api/v1/meetings/{meetingId} — A single meeting. Add ?include=agenda to include agenda data inline.

  • GET /api/v1/meetings/{meetingId}/agenda — The agenda for a meeting.

Agenda sections

  • GET /api/v1/agendas/{agendaId}/agenda-sections — List sections for an agenda (ordered by display order).

  • POST /api/v1/agendas/{agendaId}/agenda-sections — Create a section.

  • GET /api/v1/agenda-sections/{sectionId} — Get a single section.

  • PATCH /api/v1/agenda-sections/{sectionId} — Update a section. Omitted fields are left unchanged.

Agenda items

  • GET /api/v1/agenda-sections/{sectionId}/items — List items in a section.

  • POST /api/v1/agenda-sections/{sectionId}/items — Create an item.

  • GET /api/v1/agenda-items/{itemId} — Get a single item.

  • PUT /api/v1/agenda-items/{itemId} — Replace an item's updatable fields.

Agenda item statuses

  • GET /api/v1/agenda-item-statuses — List the custom statuses for your tenant (paginated).

  • GET /api/v1/agenda-item-statuses/{statusId} — Get a single status.

Documents

  • GET /api/public/projects/{projectId}/documents — Paginated list of a project's public documents.

Worked example — add an item to an agenda

A common workflow is to find a meeting, locate its agenda sections, and add an item.

1. Find the meeting and its agenda

GET /api/v1/meetings/456?include=agenda

The response includes the agendaId and its sections.

2. Pick a status to assign (statusId is required when creating an item). List the available statuses:

GET /api/v1/agenda-item-statuses

3. Create the item in a section

POST /api/v1/agenda-sections/789/itemsContent-Type: application/json{  "title": "Approval of minutes",  "description": "Review and approve the minutes from the prior meeting.",  "statusId": 5,  "speakerRegistrationEnabled": false,  "itemNumber": "1.A"}

On success the API returns 201 Created with the new item. Note that title and statusId are required, and the statusId must be a status that exists for your tenant (or a system default).

Errors

The API uses standard HTTP status codes:

  • 400 Bad Request — The request body or parameters were invalid (for example, a missing required field or an inaccessible statusId).

  • 401 Unauthorized — Missing, invalid, or expired access token. Request a new token.

  • 403 Forbidden — The token is valid but does not have access to the requested resource or tenant.

  • 404 Not Found — The resource does not exist or is not visible to your tenant.

Error responses use the same envelope, with success: false and detail in message and errors.

Tips

  • Always send X-Tenant-ID on protected calls — requests without it will fail.

  • Cache your access token and reuse it until shortly before it expires rather than requesting one per call.

  • Use the interactive Swagger documentation to see full request and response schemas and to try requests live.

If you run into trouble, reach out to support with the traceId from the failing response.

Related articles

Did this answer your question?