API Overview
Pidgr exposes a gRPC API built with Protocol Buffers. All services are available over both native gRPC (for backend services) and Connect-Web (for browser applications).
Protocol
Section titled “Protocol”- Package:
pidgr.v1 - Proto syntax:
proto3 - Transport: gRPC (HTTP/2) and Connect-Web (HTTP/1.1 + HTTP/2)
- Serialization: Protocol Buffers (binary) or JSON
Base URL
Section titled “Base URL”| Environment | URL |
|---|---|
| Production | https://api.pidgr.com |
| Staging | https://api-staging.pidgr.com |
Authentication
Section titled “Authentication”All API requests require authentication via one of:
JWT Bearer Token
Section titled “JWT Bearer Token”Issued after passkey or email OTP authentication. Include in the Authorization header:
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...The JWT contains a custom:org_id claim that scopes all requests to the authenticated organization. You never need to pass org_id in request bodies.
API Key
Section titled “API Key”For programmatic access (MCP server, CI/CD, integrations):
Authorization: Bearer pidgr_<key>API keys are scoped to an organization and inherit permissions from the organization’s role system.
Connect-Web Usage
Section titled “Connect-Web Usage”For browser and React Native clients, use Connect-Web:
import { createConnectTransport } from "@connectrpc/connect-web";import { createClient } from "@connectrpc/connect";import { CampaignService } from "@pidgr/proto/pidgr/v1/campaign_connect";
const transport = createConnectTransport({ baseUrl: "https://api.pidgr.com",});
const client = createClient(CampaignService, transport);
const response = await client.listCampaigns({ pagination: { pageSize: 10 },});gRPC Usage
Section titled “gRPC Usage”For Go backend services:
conn, err := grpc.NewClient("api.pidgr.com:443", grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),)
client := pidgrv1.NewCampaignServiceClient(conn)
resp, err := client.ListCampaigns(ctx, &pidgrv1.ListCampaignsRequest{ Pagination: &pidgrv1.Pagination{PageSize: 10},})Pagination
Section titled “Pagination”List endpoints use cursor-based pagination:
// First pageconst page1 = await client.listCampaigns({ pagination: { pageSize: 20 },});
// Next pageconst page2 = await client.listCampaigns({ pagination: { pageSize: 20, pageToken: page1.pagination.nextPageToken },});Response includes PaginationMeta with nextPageToken (empty when no more pages) and totalCount.
Error Handling
Section titled “Error Handling”The API returns standard gRPC status codes:
| Code | Meaning |
|---|---|
OK (0) | Success |
INVALID_ARGUMENT (3) | Invalid request fields |
NOT_FOUND (5) | Resource doesn’t exist |
ALREADY_EXISTS (6) | Duplicate resource |
PERMISSION_DENIED (7) | Insufficient permissions |
UNAUTHENTICATED (16) | Missing or invalid credentials |
RESOURCE_EXHAUSTED (8) | Rate limit exceeded |
INTERNAL (13) | Server error |
Error details are sanitized in production — internal error messages are never exposed to clients.
Rate Limiting
Section titled “Rate Limiting”API requests are rate-limited per organization:
- Default: 100 requests/second per organization
- Burst: 200 requests
When rate-limited, the API returns RESOURCE_EXHAUSTED with a Retry-After header.
Services
Section titled “Services”| Service | Description |
|---|---|
| ActionService | User action submission on delivered messages |
| ApiKeyService | API key management |
| CampaignService | Campaign lifecycle management |
| DeviceService | Device registration and push tokens |
| GroupService | Recipient group management |
| HeatmapService | Touch event ingestion and heatmap queries |
| InboxService | Mobile inbox sync and read tracking |
| MemberService | User management and profiles |
| OrganizationService | Organization CRUD |
| RenderService | Template rendering (internal) |
| ReplayService | Session recording replay |
| RoleService | Role and permission management |
| SSOService | SSO/SAML provider management |
| TeamService | Team management |
| TemplateService | Message template management |