ProposalAI/API Reference

API Reference

The ProposalAI REST API lets you generate AI proposals, manage team members, track engagement, and connect third-party tools — all programmatically.

● API Status: OperationalBase URL: https://api.proposalai.ai/v1

Authentication

All API requests must be authenticated using a Bearer token. Generate API keys from the Integration Hub → API Keys tab.

Authorization Header

Include your API key in every request header:
Authorization: Bearer pk_live_a1b2c3d4e5f6...

Keep your key secret

Never expose API keys in client-side code, public repositories, or URLs. Rotate compromised keys immediately from the dashboard.
Key formatEnvironmentUsage
pk_live_...ProductionReal proposals, real emails, live data

Proposals

Create, retrieve, and manage enterprise proposals.

POST/v1/proposals/generateRequires auth

Generate a proposal

Uses GPT-4o to generate a fully formatted, region-specific enterprise proposal in HTML. Automatically pulls your company branding from settings.

Request Body

userIdstringrequired

Authenticated user ID

titlestringrequired

Proposal title

clientstringrequired

Client company name

regionstringrequired

Target region (e.g. UAE, USA, UK, India). Controls laws, VAT, currency, culture context.

industrystringrequired

Client industry vertical

solutionstringrequired

Your solution / product name

scopestringoptional

Project scope and deliverables

commercialobjectoptional

Pricing object: { setup, monthly, qty, commitment }

securitystring[]optional

Security features list

apisstring[]optional

API / integration list

compliancestring[]optional

Compliance certifications

competitorsstringoptional

Known competitors in the deal

tonestringoptional

Proposal tone: formal | consultative | bold

Returns

Proposal object with id, content (HTML), title, status, and branding fields.

Error Codes

400Missing required fields
401Invalid or missing API key
500AI generation failed
curl -X POST https://api.proposalai.ai/v1/proposals/generate \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_abc123",
    "title": "AI-Powered Video Analytics for Dubai Metro",
    "client": "RTA Dubai",
    "region": "UAE",
    "industry": "Smart Mobility",
    "solution": "ProposalAI AI Analytics Suite",
    "commercial": {
      "setup": 250000,
      "monthly": 18000,
      "qty": 1,
      "commitment": 36
    }
  }'
POST/v1/proposals/rfpRequires auth

Analyze RFP & generate proposal

Upload a PDF, DOCX, or TXT RFP document. ProposalAI extracts requirements, compliance needs, and evaluation criteria, then generates a matching proposal.

Request Body

fileFilerequired

RFP document (PDF, DOCX, or TXT). Send as multipart/form-data.

userIdstringoptional

If provided, saves the proposal to the user's account.

Returns

RFP structured extraction + generated proposal content.

Error Codes

400No file provided
500Parse or generation failed
curl -X POST https://api.proposalai.ai/v1/proposals/rfp \
  -H "Authorization: Bearer pk_live_••••" \
  -F "file=@RFP_Document.pdf" \
  -F "userId=user_abc123"
POST/v1/proposals/sendRequires auth

Send proposal via email

Send a proposal to a client email with open tracking pixel and click tracking link embedded automatically.

Request Body

proposalIdstringrequired

ID of the proposal to send

emailstringrequired

Recipient email address

titlestringoptional

Email subject line (defaults to proposal title)

contentstringoptional

Proposal HTML content to embed in the email

Returns

{ success: true } on delivery.

Error Codes

400Missing email or content
500Email delivery failed
curl -X POST https://api.proposalai.ai/v1/proposals/send \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{
    "proposalId": "prop_9f3a2c1e",
    "email": "cto@rtadubai.ae",
    "title": "Your AI Analytics Proposal from Acme Corp"
  }'

Tracking & Analytics

Real-time engagement tracking for sent proposals. These endpoints update the deal score, views, clicks, and open status on proposals.

POST/v1/tracking/view

Record a proposal view

Increments the view counter and updates last_viewed timestamp. Updates deal score automatically.

Request Body

idstringrequired

Proposal ID

Returns

{ success: true, views: number }

curl -X POST https://api.proposalai.ai/v1/tracking/view \
  -H "Content-Type: application/json" \
  -d '{ "id": "prop_9f3a2c1e" }'
GET/v1/tracking/open

Email open tracking pixel

Returns a 1×1 transparent GIF. Embed in proposal emails to detect when the recipient opens the email. Sets opened=true on first load.

Query Parameters

idstringrequired

Proposal ID

Returns

1×1 GIF image (image/gif). Side effect: marks proposal as opened.

<!-- Embed in email HTML -->
<img src="https://api.proposalai.ai/v1/tracking/open?id=prop_9f3a2c1e"
     width="1" height="1" />
GET/v1/tracking/click

Email click tracking redirect

Increments the click counter then redirects to the proposal share page. Use as the href in proposal email CTAs.

Query Parameters

idstringrequired

Proposal ID

Returns

302 redirect to /share/{id}

<!-- Wrap your CTA button -->
<a href="https://api.proposalai.ai/v1/tracking/click?id=prop_9f3a2c1e">
  View Proposal
</a>

Team & Invitations

Manage team members and send branded invitation emails.

POST/v1/team/inviteRequires auth

Invite a team member

Creates a team member record with status 'Invited', generates a secure token, and sends a branded HTML invitation email via Resend.

Request Body

ownerIdstringrequired

The inviting user's ID

namestringrequired

Invitee full name

emailstringrequired

Invitee email address

rolestringrequired

Role: Admin | Manager | Viewer | Editor

permissionsstring[]optional

List of permission strings, e.g. ['proposals:create', 'proposals:send']

Returns

{ success: true, memberId, inviteUrl }

Error Codes

400Missing required fields
500Failed to send email or create record
curl -X POST https://api.proposalai.ai/v1/team/invite \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{
    "ownerId": "user_abc123",
    "name": "Sara Ahmed",
    "email": "sara@yourcompany.com",
    "role": "Manager",
    "permissions": ["proposals:create", "proposals:send", "proposals:view"]
  }'
POST/v1/team/accept

Accept an invitation

Called after the invitee completes signup or login on the invite page. Marks the member as Active and links their auth user ID.

Request Body

memberIdstringrequired

Team member record ID from the invite lookup

userIdstringrequired

Supabase auth user ID of the invitee

Returns

{ success: true }

curl -X POST https://api.proposalai.ai/v1/team/accept \
  -H "Content-Type: application/json" \
  -d '{
    "memberId": "mem_3f2a1c",
    "userId": "auth_user_xyz"
  }'

Integrations

Manage third-party integration connections for your account.

GET/v1/integrationsRequires auth

List integrations

Returns the connection status and masked config for all integrations linked to the user.

Query Parameters

userIdstringrequired

User ID

Returns

Array of integration objects with name, status, config (masked), and updated_at.

curl https://api.proposalai.ai/v1/integrations?userId=user_abc123 \
  -H "Authorization: Bearer pk_live_••••"
POST/v1/integrations/connectRequires auth

Connect an integration

Validates credentials against the third-party API, then saves the masked config. Supported: Salesforce, HubSpot, Slack, Stripe, Neon, and more.

Request Body

userIdstringrequired

User ID

integrationNamestringrequired

Integration name, e.g. 'Salesforce', 'HubSpot', 'Slack'

configobjectrequired

Credential key-value pairs specific to the integration

Returns

{ success: true }

Error Codes

422Credential validation failed (wrong key, invalid URL, etc.)
500Database error
curl -X POST https://api.proposalai.ai/v1/integrations/connect \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_abc123",
    "integrationName": "HubSpot",
    "config": {
      "access_token": "pat-na1-xxxxxxxx",
      "portal_id": "12345678"
    }
  }'
POST/v1/integrations/disconnectRequires auth

Disconnect an integration

Removes stored credentials and sets status to disconnected.

Request Body

userIdstringrequired

User ID

integrationNamestringrequired

Integration name to disconnect

Returns

{ success: true }

curl -X POST https://api.proposalai.ai/v1/integrations/disconnect \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_abc123",
    "integrationName": "HubSpot"
  }'

API Keys

Programmatically manage API keys for your ProposalAI account.

GET/v1/api-keysRequires auth

List API keys

Returns all active API keys for the user. Key values are partially masked.

Query Parameters

userIdstringrequired

User ID

Returns

Array of API key objects.

curl https://api.proposalai.ai/v1/api-keys?userId=user_abc123 \
  -H "Authorization: Bearer pk_live_••••"
POST/v1/api-keysRequires auth

Create API key

Generates a new pk_live_... API key. The full key value is only returned once at creation time.

Request Body

userIdstringrequired

User ID

namestringrequired

Descriptive name for the key (e.g. Production, CI/CD)

Returns

New key object including the full key_value (only shown once).

curl -X POST https://api.proposalai.ai/v1/api-keys \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{ "userId": "user_abc123", "name": "Production" }'
DELETE/v1/api-keys/{id}Requires auth

Revoke API key

Permanently revokes the specified API key. Any requests using this key will immediately fail with 401.

Query Parameters

userIdstringrequired

User ID

Returns

{ success: true }

curl -X DELETE "https://api.proposalai.ai/v1/api-keys/key_4d5e6f?userId=user_abc123" \
  -H "Authorization: Bearer pk_live_••••"

Webhooks

Register HTTP endpoints to receive real-time event notifications from ProposalAI.

GET/v1/webhooksRequires auth

List webhooks

Returns all configured webhook endpoints for the user.

Query Parameters

userIdstringrequired

User ID

Returns

Array of webhook objects.

curl https://api.proposalai.ai/v1/webhooks?userId=user_abc123 \
  -H "Authorization: Bearer pk_live_••••"
POST/v1/webhooksRequires auth

Create webhook

Registers a new webhook endpoint. A whsec_... signing secret is auto-generated and returned. Use it to verify incoming webhook signatures.

Request Body

userIdstringrequired

User ID

namestringrequired

Display name

urlstringrequired

HTTPS endpoint URL

eventsstring[]optional

Event types to subscribe to. Omit to receive all events.

Returns

Webhook object including the signing secret (shown in full only once).

curl -X POST https://api.proposalai.ai/v1/webhooks \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_abc123",
    "name": "CRM Sync",
    "url": "https://yourapp.com/webhooks/proposalai",
    "events": ["proposal.created", "proposal.accepted", "payment.received"]
  }'
PATCH/v1/webhooks/{id}Requires auth

Pause / resume webhook

Toggle a webhook between active and paused states without deleting it.

Request Body

userIdstringrequired

User ID

activebooleanrequired

true to resume, false to pause

Returns

{ success: true }

curl -X PATCH https://api.proposalai.ai/v1/webhooks/wh_a9b8c7 \
  -H "Authorization: Bearer pk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{ "userId": "user_abc123", "active": false }'
DELETE/v1/webhooks/{id}Requires auth

Delete webhook

Permanently removes a webhook endpoint.

Query Parameters

userIdstringrequired

User ID

Returns

{ success: true }

curl -X DELETE "https://api.proposalai.ai/v1/webhooks/wh_a9b8c7?userId=user_abc123" \
  -H "Authorization: Bearer pk_live_••••"

Error Codes

ProposalAI uses standard HTTP status codes. All error responses include a JSON body with an error field.

CodeStatusMeaning
200OKRequest succeeded.
400Bad RequestMissing or invalid parameters. Check the error message.
401UnauthorizedMissing or invalid API key.
403ForbiddenValid key but insufficient permissions.
404Not FoundThe requested resource does not exist.
410GoneResource existed but is no longer available (e.g. used invite).
422Unprocessable EntityValidation failed — e.g. invalid credentials when connecting an integration.
429Too Many RequestsRate limit exceeded. Retry after the Retry-After header value.
500Internal Server ErrorSomething went wrong on our end. Contact support.

Error response format

{
  "error": "Credential validation failed. Check your Instance URL and Access Token."
}

Webhook Events

Subscribe to specific events when creating a webhook. All payloads are signed with your whsec_... secret using HMAC-SHA256.

EventDescription
proposal.createdA new proposal was generated
proposal.sentA proposal was emailed to a client
proposal.viewedClient opened the proposal share link
proposal.acceptedClient accepted the proposal
proposal.rejectedClient rejected the proposal
proposal.expiredProposal passed its expiry date
team.member_invitedA team invitation was sent
team.member_joinedAn invitee accepted and joined the team
payment.receivedA payment was successfully collected

Verifying webhook signatures

import crypto from "crypto"

function verifyWebhook(payload: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex")
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  )
}

// In your endpoint handler:
const sig    = req.headers["x-proposalai-signature"]
const body   = await req.text()
const valid  = verifyWebhook(body, sig, process.env.WEBHOOK_SECRET!)

if (!valid) return res.status(401).send("Invalid signature")

Rate Limits

Rate limits are applied per API key. Exceeding limits returns a 429 response with a Retry-After header.

EndpointLimitWindow
POST /proposals/generate20 requestsper minute
POST /proposals/rfp10 requestsper minute
All other endpoints100 requestsper minute

ProposalAI API v1 · Questions? Email support@proposalai.ai

We use essential cookies to keep you signed in and analytics cookies to improve the product. Learn more.