AIGov
API Reference

AiGov API Documentation

Integrate AI governance workflows into your tools and processes. Manage initiatives, automate technology intake, query your tech inventory, and build custom dashboards — all through a secure, RESTful API.

Overview

The AiGov API is organized around REST principles. It accepts JSON request bodies, returns JSON responses, and uses standard HTTP response codes.

RESTful

Predictable, resource-oriented URLs with standard HTTP verbs.

Secure

TLS-only with application-level tenant isolation and role-based access control.

Multi-tenant

Tenant isolation enforced at the database level on every request.

Authentication

All API requests require authentication. AiGov uses Auth.js v5 with Microsoft Entra ID (Azure AD) OAuth 2.0. Browser clients authenticate via session cookies; server-to-server integrations use Bearer tokens from the /api/auth endpoints.

Session Cookie (Browser)
# Browser clients are automatically authenticated via HTTP-only session cookies
# set by the Auth.js /api/auth/* endpoints. No manual header needed.
Cookie: authjs.session-token=<session-token>
// Browser: redirect to Microsoft Entra ID login
import { signIn } from 'next-auth/react'

await signIn('microsoft-entra-id', {
  redirectTo: '/dashboard'
})

// Server-side: get session in API routes or server actions
import { auth } from '@/lib/auth/auth'

const session = await auth()
const userId = session?.user?.id

Keep your tokens secure

Never expose your AUTH_SECRET or AUTH_MICROSOFT_ENTRA_ID_SECRET in client-side code. Session tokens are HTTP-only cookies and cannot be accessed via JavaScript. Server-side integrations should use environment variables for secrets.

Base URL

All API requests are made against your AiGov deployment URL. The API is served through Next.js API routes and server actions.

# REST API (v1)
https://portal.aigov.technostica.net/api/v1/

# Auth.js Endpoints
https://portal.aigov.technostica.net/api/auth/signin
https://portal.aigov.technostica.net/api/auth/signout
https://portal.aigov.technostica.net/api/auth/session

# Chat (SSE streaming)
https://portal.aigov.technostica.net/api/chat

# Text-to-Speech
https://portal.aigov.technostica.net/api/tts

# Audit Log Export
https://portal.aigov.technostica.net/api/export/audit-logs

Rate Limits

Rate limits protect against abuse and ensure fair usage for all tenants.

EndpointLimitWindow
Intake Chat Messages50 requestsPer user, per hour
Initiative Creation10 requestsPer user, per day
REST API (general)1,000 requestsPer user, per hour
Audit Log Export10 requestsPer admin, per hour
Rate Limit Exceeded Response (429)
{
  "error": "Rate limit exceeded. Please try again later.",
  "remaining": 0
}

Errors

AiGov uses conventional HTTP status codes to indicate the success or failure of a request.

CodeStatusDescription
200OKRequest succeeded.
201CreatedResource created successfully.
400Bad RequestInvalid request body or parameters.
401UnauthorizedMissing or invalid authentication token.
403ForbiddenInsufficient role or permissions.
404Not FoundResource does not exist or is inaccessible.
409ConflictResource already exists or state conflict.
429Too Many RequestsRate limit exceeded.
500Internal Server ErrorSomething went wrong on our end.
Error Response Format
{
  "error": "A human-readable error message",
  "code": "ERROR_CODE",
  "details": "Additional context when available"
}

Initiatives

Initiatives are the core resource in AiGov. They represent technology requests that move through the governance workflow — from intake through functional review and enterprise approval.

The Initiative Object

Initiative Object
{
  "id": "uuid",
  "tenant_id": "uuid",
  "submitter_id": "uuid",
  "title": "Slack for Engineering",
  "vendor": "Slack Technologies",
  "licensing_model": "SaaS per-user subscription",
  "deployment_model": "cloud",        // "cloud" | "on_prem" | "hybrid"
  "data_handling": ["internal-only"],
  "user_scope": "employee",           // "employee" | "customer" | "both"
  "queue_id": "uuid",
  "problem_statement": "Need real-time messaging for distributed teams",
  "business_value": "Improve cross-team communication efficiency by 40%",
  "estimated_users": 250,
  "urgency": "quarter",               // "immediate" | "quarter" | "next_fiscal_year"
  "current_stage": "functional_review",// "intake" | "functional_review" | "enterprise_workflow"
  "current_status": "Pending Review",
  "matched_tool_id": null,
  "created_tool_id": null,
  "intake_document": { ... },
  "created_at": "2026-03-01T12:00:00Z",
  "updated_at": "2026-03-01T14:30:00Z"
}
GET/api/v1/initiativesSession Cookie

List initiatives for the authenticated user. Use ?scope=enterprise for all tenant initiatives, or ?queue_id=<id> for a specific queue. Default returns the user's own initiatives.

ParameterTypeRequiredDescription
scopestringOptional"enterprise" to list all tenant initiatives
queue_iduuidOptionalFilter by functional queue
// List my initiatives
const res = await fetch('/api/v1/initiatives', { credentials: 'include' })
const { data } = await res.json()

// List all enterprise initiatives
const all = await fetch('/api/v1/initiatives?scope=enterprise', { credentials: 'include' })

// Get a single initiative
const detail = await fetch('/api/v1/initiatives/550e8400-...', { credentials: 'include' })
const { data: initiative } = await detail.json()
POST/api/v1/initiativesSession Cookie

Create a new initiative in Drafting status. Typically created automatically when a user starts the intake chatbot.

const res = await fetch('/api/v1/initiatives', {
  method: 'POST',
  credentials: 'include'
})
const { data } = await res.json() // { id: "uuid", ... }
POST/api/v1/initiatives/:id/transitionSession Cookie (role-dependent)

Transition an initiative to a new status. Validates against the workflow state machine. Every transition requires a mandatory comment.

ParameterTypeRequiredDescription
newStatusstringRequiredTarget status (validated by state machine)
commentstringRequiredMandatory explanation for the transition
const res = await fetch('/api/v1/initiatives/550e8400-.../transition', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({
    newStatus: 'Approved for Prototype',
    comment: 'Meets all requirements. Approved for pilot deployment.'
  })
})
const result = await res.json()
DELETE/api/v1/initiatives/:idSession Cookie (submitter only)

Delete a draft initiative. Only allowed when current_status is "Drafting" and the request is made by the submitter.

cURL
curl -X DELETE 'https://portal.aigov.technostica.net/api/v1/initiatives/<id>' \
  -H 'Cookie: authjs.session-token=<token>'

Intake Chat

The AI-powered intake chatbot conducts conversational interviews to collect initiative information. It streams responses via Server-Sent Events (SSE).

POST/api/chatBearer Token

Send a message to the intake chatbot. Returns a streaming SSE response with text deltas, tool results, and completion events.

ParameterTypeRequiredDescription
messagestringRequiredThe user message to send to the chatbot
initiativeIduuidRequiredID of the initiative this conversation belongs to
const response = await fetch('/api/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    message: 'I need a project management tool for our engineering team',
    initiativeId: '550e8400-e29b-41d4-a716-446655440000'
  })
})

const reader = response.body!.getReader()
const decoder = new TextDecoder()

while (true) {
  const { done, value } = await reader.read()
  if (done) break
  const chunk = decoder.decode(value)
  for (const line of chunk.split('\n')) {
    if (line.startsWith('data: ')) {
      const event = JSON.parse(line.slice(6))
      if (event.type === 'text') process.stdout.write(event.text)
      if (event.type === 'done') console.log('\n--- Done ---')
    }
  }
}

SSE Event Types

Event TypePayload
textStreaming text delta from the AI assistant
tool_resultResult from a tool call (inventory search, web search, submission)
user_message_idPersisted user message ID for client tracking
doneStream complete; includes assistant_message_id
errorError message if something went wrong
SSE Response Stream
data: {"type":"user_message_id","id":"msg_abc123"}

data: {"type":"text","text":"I'd be happy to help you find a project management"}
data: {"type":"text","text":" tool. Let me search your organization's inventory..."}

data: {"type":"tool_result","tool":"search_tech_inventory","results":[...]}

data: {"type":"text","text":"I found a few existing tools..."}

data: {"type":"done","assistant_message_id":"msg_def456"}

Available Chat Tools

The chatbot has access to the following tools that it invokes automatically during conversations:

update_title

Sets the initiative title based on conversation context

search_tech_inventory

Searches the org tech inventory for existing solutions

web_search

Searches the web for vendor/tool information via Tavily

search_initiatives

Searches existing initiatives to detect in-flight duplicates

submit_initiative

Submits the initiative after user confirmation

resolve_initiative

Resolves by connecting user to existing tool owner

GET/api/v1/initiatives/:id/chatSession Cookie

Retrieve the chat message history for an initiative. Returns all user, assistant, and system (tool result) messages in chronological order.

const res = await fetch('/api/v1/initiatives/550e8400-.../chat', {
  credentials: 'include'
})
const { data: messages } = await res.json()
// messages: [{ role, content, created_at }, ...]

Documents

Upload and manage file attachments on initiatives. Supports PDF, DOCX, XLSX, PNG, JPG, and SVG files up to 10 MB each (max 5 per submission). Files are stored in Google Cloud Storage.

GET/api/v1/initiatives/:id/documentsSession Cookie

List all documents attached to an initiative.

const res = await fetch('/api/v1/initiatives/<id>/documents', {
  credentials: 'include'
})
const { data: docs } = await res.json()
// docs: [{ id, file_name, file_type, file_size, uploaded_at }, ...]
POST/api/v1/initiatives/:id/documentsSession Cookie (role-dependent)

Upload a document to an initiative. Send as multipart/form-data. Upload permissions are stage-based (see PRD section 4.8).

ParameterTypeRequiredDescription
fileFileRequiredThe file to upload (max 10 MB)
const formData = new FormData()
formData.append('file', fileInput.files[0])

const res = await fetch('/api/v1/initiatives/<id>/documents', {
  method: 'POST',
  credentials: 'include',
  body: formData
})
const { data } = await res.json()
DELETE/api/v1/initiatives/:id/documents/:docIdSession Cookie (uploader or Admin)

Delete a document from an initiative.

Investment Asks

Manage resource requests (human capital) and financial requests (line-item costs) attached to initiatives. These are added by Function Leads when approving for scaling.

POST/api/v1/initiatives/:id/resourcesSession Cookie (Function Lead / Admin)

Add a resource request (human capital) to an initiative.

ParameterTypeRequiredDescription
rolestringRequiredJob title or function needed
quantitynumberRequiredNumber of people
duration_monthsnumberRequiredDuration in months
locationstringRequiredOn-site, remote, or offshore
pay_ratenumberRequiredPay rate amount
pay_frequencyenumRequired"hourly", "monthly", or "annual"
const res = await fetch('/api/v1/initiatives/<id>/resources', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({
    role: 'Cloud Engineer',
    quantity: 2,
    duration_months: 6,
    location: 'Remote',
    pay_rate: 85,
    pay_frequency: 'hourly'
  })
})
DELETE/api/v1/initiatives/:id/resourcesSession Cookie (Function Lead / Admin)

Delete a resource request by ID.

ParameterTypeRequiredDescription
resourceIduuidRequiredID of the resource request to delete
POST/api/v1/initiatives/:id/financialsSession Cookie (Function Lead / Admin)

Add a financial request (line-item cost) to an initiative.

ParameterTypeRequiredDescription
categoryenumRequired"licensing", "infrastructure", "implementation", "training", or "other"
descriptionstringRequiredDetails of the cost item
amountnumberRequiredEstimated cost amount
frequencyenumRequired"one_time", "monthly", or "annual"
const res = await fetch('/api/v1/initiatives/<id>/financials', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({
    category: 'licensing',
    description: 'Annual SaaS license for 250 seats',
    amount: 45000,
    frequency: 'annual'
  })
})
DELETE/api/v1/initiatives/:id/financialsSession Cookie (Function Lead / Admin)

Delete a financial request by ID.

ParameterTypeRequiredDescription
financialIduuidRequiredID of the financial request to delete

Tech Inventory

The tech inventory tracks all approved and active technology tools across the organization. It supports full-text and semantic search.

GET/api/v1/inventorySession Cookie

List tech inventory items for the tenant. Supports search by tool name, vendor, and description using pg_trgm fuzzy matching.

ParameterTypeRequiredDescription
searchstringOptionalSearch query (fuzzy matches tool_name, vendor, description)
statusstringOptional"active", "deprecated", or "under_review"
// List all inventory items
const res = await fetch('/api/v1/inventory', { credentials: 'include' })
const { data } = await res.json()

// Search with fuzzy matching
const search = await fetch('/api/v1/inventory?search=project+management', {
  credentials: 'include'
})
const { data: results } = await search.json()
POST/api/v1/inventorySession Cookie (Admin)

Create a new tech inventory entry. Admin role required. Items are also auto-created when initiatives reach Enterprise Approved status.

ParameterTypeRequiredDescription
tool_namestringRequiredName of the tool
vendorstringRequiredVendor name
categorystringRequiredTool category
departmentstringRequiredOwning department
descriptionstringOptionalTool description
statusenumOptional"active", "deprecated", or "under_review"
const res = await fetch('/api/v1/inventory', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({
    tool_name: 'Jira',
    vendor: 'Atlassian',
    category: 'Engineering',
    department: 'Technology',
    description: 'Project tracking and agile management',
    status: 'active'
  })
})
const { data } = await res.json()
PATCH/api/v1/inventory/:idSession Cookie (Admin)

Update an existing tech inventory entry. Admin role required.

cURL
curl -X PATCH 'https://portal.aigov.technostica.net/api/v1/inventory/<id>' \
  -H 'Content-Type: application/json' \
  -H 'Cookie: authjs.session-token=<token>' \
  -d '{"status": "deprecated"}'
DELETE/api/v1/inventory/:idSession Cookie (Admin)

Delete a tech inventory entry. Admin role required.

Functional Queues

Functional queues route initiatives to the appropriate department for review. Each queue has assigned function leads who manage incoming submissions.

GET/api/v1/queuesSession Cookie

List all functional queues for the tenant.

Queue Object
{
  "id": "uuid",
  "tenant_id": "uuid",
  "name": "Engineering",
  "description": "Engineering tools and infrastructure requests",
  "webhook_url": "https://outlook.office.com/webhook/...",
  "is_active": true,
  "created_at": "2026-01-15T09:00:00Z",
  "updated_at": "2026-01-15T09:00:00Z"
}
const res = await fetch('/api/v1/queues', { credentials: 'include' })
const { data: queues } = await res.json()
for (const q of queues) {
  console.log(q.name, q.is_active ? '(active)' : '(inactive)')
}
POST/api/v1/queuesSession Cookie (Admin)

Create a new functional queue.

ParameterTypeRequiredDescription
namestringRequiredQueue name (e.g., "Engineering", "Marketing")
descriptionstringOptionalQueue description (used by AI for routing context)
webhook_urlstringOptionalMicrosoft Teams webhook URL for new submission notifications
is_activebooleanOptionalWhether the queue accepts submissions (default: true)
const res = await fetch('/api/v1/queues', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({ name: 'Regulatory', description: 'Compliance and regulatory tools' })
})
const { data } = await res.json()
PATCH/api/v1/queues/:idSession Cookie (Admin)

Update a functional queue.

cURL
curl -X PATCH 'https://portal.aigov.technostica.net/api/v1/queues/<id>' \
  -H 'Content-Type: application/json' \
  -H 'Cookie: authjs.session-token=<token>' \
  -d '{"is_active": false}'
DELETE/api/v1/queues/:idSession Cookie (Admin)

Deactivate a functional queue (soft delete).

Reviews & Comments

Comments track all feedback, status transitions, and review decisions on initiatives. Review checklists track security and legal review completion.

GET/api/v1/initiatives/:id/commentsSession Cookie

List all comments on an initiative, including status change records and review feedback.

Comment Object
{
  "id": "uuid",
  "initiative_id": "uuid",
  "author_id": "uuid",
  "content": "Approved — meets all security requirements.",
  "review_type": "security",      // "security" | "legal" | null
  "traffic_light": "green",       // "green" | "yellow" | "red" | null
  "status_change_from": "Pending Review",
  "status_change_to": "Approved for Prototype",
  "created_at": "2026-03-02T10:00:00Z"
}
const res = await fetch('/api/v1/initiatives/<id>/comments', { credentials: 'include' })
const { data: comments } = await res.json()
POST/api/v1/initiatives/:id/commentsSession Cookie (role-dependent)

Add a comment or review decision to an initiative.

ParameterTypeRequiredDescription
contentstringRequiredComment text or review feedback
review_typeenumOptional"security" or "legal" for review comments
traffic_lightenumOptional"green", "yellow", or "red" risk assessment
status_change_tostringOptionalNew status if this comment triggers a transition
const res = await fetch('/api/v1/initiatives/<id>/comments', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({
    content: 'Approved — meets all security requirements.',
    review_type: 'security',
    traffic_light: 'green'
  })
})
GET/api/v1/initiatives/:id/reviewsSession Cookie

Get security and legal review checklists for an initiative.

Review Checklist Object
{
  "id": "uuid",
  "initiative_id": "uuid",
  "review_type": "security",
  "is_completed": true,
  "traffic_light": "green",
  "reviewer_id": "uuid",
  "completed_at": "2026-03-02T11:00:00Z"
}
cURL
curl 'https://portal.aigov.technostica.net/api/v1/initiatives/<id>/reviews' \
  -H 'Cookie: authjs.session-token=<token>'
GET/api/v1/reviews/pendingSession Cookie

Get all reviews pending for the current user across all initiatives.

cURL
curl 'https://portal.aigov.technostica.net/api/v1/reviews/pending' \
  -H 'Cookie: authjs.session-token=<token>'

Audit Logs

Immutable audit trail of all actions in the platform. Every status change, review, and submission is recorded with full context.

GET/api/export/audit-logs?format=jsonSession Cookie (Admin)

Query audit logs for the tenant. Returns JSON when format=json is specified, or CSV by default.

Audit Log Object
{
  "id": "uuid",
  "initiative_id": "uuid",
  "actor_id": "uuid",
  "action": "status_change",
  "details": {
    "from": "Drafting",
    "to": "Pending Review",
    "via": "chatbot_submission"
  },
  "created_at": "2026-03-01T14:30:00Z"
}
GET/api/export/audit-logsSession Cookie (Admin)

Export all audit logs. Returns CSV by default, or JSON when ?format=json is appended. Headers: id, initiative_id, actor_id, action, details, created_at.

const response = await fetch('/api/export/audit-logs?format=json', {
  credentials: 'include'
})
const logs = await response.json()
console.log(`Found ${logs.length} audit log entries`)

Notifications

In-app and email notifications for status changes, new submissions, review requests, and tool owner connections.

GET/api/v1/notificationsSession Cookie

Retrieve notifications for the authenticated user. Use ?count_only=true to get just the unread count. Supports ?limit= for pagination.

ParameterTypeRequiredDescription
limitnumberOptionalMax notifications to return
count_onlybooleanOptionalReturn only unread count
Notification Object
{
  "id": "uuid",
  "recipient_id": "uuid",
  "initiative_id": "uuid",
  "type": "status_change",     // "status_change" | "new_submission" |
                                // "review_required" | "mention" | "connect_to_owner"
  "message": "Your initiative \"Slack for Engineering\" moved to Pending Review",
  "read": false,
  "email_sent": true,
  "created_at": "2026-03-01T14:30:00Z"
}
// Get notifications
const res = await fetch('/api/v1/notifications?limit=20', { credentials: 'include' })
const { data } = await res.json()

// Get unread count only
const count = await fetch('/api/v1/notifications?count_only=true', { credentials: 'include' })
const { data: unreadCount } = await count.json()
PATCH/api/v1/notificationsSession Cookie

Mark one or more notifications as read.

ParameterTypeRequiredDescription
iduuidRequiredNotification ID to mark as read
cURL
curl -X PATCH 'https://portal.aigov.technostica.net/api/v1/notifications' \
  -H 'Content-Type: application/json' \
  -H 'Cookie: authjs.session-token=<token>' \
  -d '{"id": "<notification-id>"}'
DELETE/api/v1/notificationsSession Cookie

Clear all notifications for the authenticated user.

cURL
curl -X DELETE 'https://portal.aigov.technostica.net/api/v1/notifications' \
  -H 'Cookie: authjs.session-token=<token>'

Notification Types

status_change — Initiative status was updated

new_submission — New initiative submitted to a queue

review_required — Security or legal review needed

mention — User was mentioned in a comment

connect_to_owner — Someone wants to connect about your tool

Users & Roles

Manage user profiles and role-based access control. AiGov supports six roles with granular permissions.

RolePermissions
publicSubmit initiatives, view own submissions, chat with intake bot
function_leadReview queue submissions, approve/reject at functional level, manage queue
enterprise_leadEnterprise-stage reviews, scaling decisions, final approvals
security_reviewerSecurity review checklists, risk assessments, traffic light ratings
legal_reviewerLegal review checklists, compliance assessments, traffic light ratings
adminFull tenant management: users, queues, audit logs, settings
GET/api/v1/usersSession Cookie (Admin)

List user profiles for the tenant with their assigned roles. Supports search and role filtering.

ParameterTypeRequiredDescription
searchstringOptionalSearch by name or email
rolestringOptionalFilter by role
Profile Object
{
  "id": "uuid",
  "tenant_id": "uuid",
  "email": "jane@example.com",
  "full_name": "Jane Smith",
  "avatar_url": "https://...",
  "notification_preference": "per_event",  // "per_event" | "daily_digest"
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-03-01T00:00:00Z"
}
const res = await fetch('/api/v1/users?search=jane', { credentials: 'include' })
const { data: users } = await res.json()
GET/api/v1/users/:idSession Cookie (Admin)

Get a single user profile with role details.

User Role Object
{
  "id": "uuid",
  "user_id": "uuid",
  "tenant_id": "uuid",
  "role": "function_lead",
  "queue_id": "uuid",       // null for non-queue-specific roles
  "assigned_at": "2026-01-15T00:00:00Z"
}
POST/api/v1/users/:id/rolesSession Cookie (Admin)

Assign a role to a user.

ParameterTypeRequiredDescription
roleenumRequiredOne of the six available roles
queue_iduuidOptionalQueue ID (required for function_lead role)
const res = await fetch('/api/v1/users/<user-id>/roles', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  credentials: 'include',
  body: JSON.stringify({ role: 'function_lead', queue_id: '<queue-id>' })
})
DELETE/api/v1/users/:id/rolesSession Cookie (Admin)

Revoke a role from a user.

ParameterTypeRequiredDescription
roleenumRequiredRole to revoke
queue_iduuidOptionalQueue ID (for function_lead role)
GET/api/v1/profileSession Cookie

Get the current user's profile.

cURL
curl 'https://portal.aigov.technostica.net/api/v1/profile' \
  -H 'Cookie: authjs.session-token=<token>'
PATCH/api/v1/profileSession Cookie

Update the current user's profile (notification preferences, etc.).

cURL
curl -X PATCH 'https://portal.aigov.technostica.net/api/v1/profile' \
  -H 'Content-Type: application/json' \
  -H 'Cookie: authjs.session-token=<token>' \
  -d '{"notification_preference": "daily_digest"}'

Dashboard Analytics

REST endpoints that power the analytics dashboard. Use these to build custom reports and integrations.

GET/api/v1/dashboardSession Cookie

Fetch dashboard analytics. Returns all sections by default, or use ?section= to fetch a specific one. Supports ?months= for time range.

ParameterTypeRequiredDescription
sectionstringOptional"by-function", "funnel", "volume", or "approval". Omit for all.
monthsnumberOptionalNumber of months for trends (default: 12)
// Get all dashboard data
const res = await fetch('/api/v1/dashboard', { credentials: 'include' })
const { data } = await res.json()
console.log(data.byFunction, data.funnel, data.volume, data.approval)

// Get a specific section
const volume = await fetch('/api/v1/dashboard?section=volume&months=6', {
  credentials: 'include'
})
const { data: trends } = await volume.json()
Dashboard Response Shape (all sections)
{
  "success": true,
  "data": {
    "byFunction": [
      { "queue_name": "Engineering", "count": 45, "statuses": {...} },
      { "queue_name": "Marketing", "count": 32, "statuses": {...} }
    ],
    "funnel": [
      { "stage": "drafting", "count": 142 },
      { "stage": "submitted", "count": 130 }
    ],
    "volume": [
      { "month": "2026-01", "intake": 12, "functional": 8, "enterprise": 3 }
    ],
    "approval": [
      { "month": "2026-01", "approved": 5, "rejected": 2, "rate": 0.71 }
    ]
  }
}

Text-to-Speech

Convert text to audio using Google Cloud Text-to-Speech. Used by the blog read-aloud feature. Rate limited to 10 requests per minute per IP.

POST/api/ttsNo authentication required

Convert text to speech audio. Returns an MP3 audio buffer. Automatically chunks long text to stay within Google Cloud TTS limits.

ParameterTypeRequiredDescription
textstringRequiredThe text to convert to speech
const res = await fetch('/api/tts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ text: 'Hello, welcome to AiGov.' })
})
const audioBlob = await res.blob()
const audioUrl = URL.createObjectURL(audioBlob)
const audio = new Audio(audioUrl)
audio.play()

Real-time Updates

AiGov uses polling-based real-time updates for notifications and data changes. The intake chat uses Server-Sent Events (SSE) for streaming AI responses.

import { useNotifications } from '@/hooks/use-notifications'

// Polls every 10 seconds for new notifications
useNotifications((notification) => {
  console.log('New notification:', notification.message)
  // Show toast, update badge count, etc.
})

// Generic polling hook for data changes
import { useRealtime } from '@/hooks/use-realtime'

useRealtime({
  table: 'initiatives',
  event: '*',
  interval: 5000,
  onData: (payload) => {
    router.refresh()
  }
})

Real-time Capabilities

SSE streaming — AI chat responses stream in real-time via /api/chat

Notification polling — New notifications detected every 10 seconds

Data polling — Configurable interval polling for any table changes

Email notifications — Instant email delivery via Resend on status changes and @mentions

Teams webhooks — Per-queue Microsoft Teams Adaptive Card notifications for new submissions

SDKs & Libraries

AiGov is built with Next.js server actions and API routes. Use these libraries for integration.

TypeScript (Server Actions)

next-auth + drizzle-orm
npm install next-auth@beta drizzle-orm

Python (HTTP Client)

requests
pip install requests

CLI (cURL)

curl
Built into macOS/Linux; Windows: winget install curl

Database (Direct)

psql / pg
psql postgresql://user:pass@host:5432/aigov
// Authentication is handled by Auth.js with Microsoft Entra ID
import { signIn } from 'next-auth/react'
await signIn('microsoft-entra-id')

// List initiatives
const initiatives = await fetch('/api/v1/initiatives', { credentials: 'include' })
const { data } = await initiatives.json()

// Search tech inventory
const search = await fetch('/api/v1/inventory?search=project+management', {
  credentials: 'include'
})
const { data: results } = await search.json()

// Get dashboard analytics
const dash = await fetch('/api/v1/dashboard', { credentials: 'include' })
const { data: dashboard } = await dash.json()
console.log(dashboard.byFunction, dashboard.volume)

Need Help?

Need help integrating with the AiGov API or building custom governance workflows? Reach out to the Technostica AiGov team.