Inbox Agent API and Service Contract Specification
1. Purpose
This document defines the service boundaries, API responsibilities, command/query contracts, integration rules, and client-facing interfaces for the Inbox Agent platform.
The goals are to:
- Keep UI clients independent of provider APIs.
- Keep provider-specific logic behind adapters.
- Support both web and future native iOS clients.
- Separate read/query operations from mailbox mutations.
- Force all mutations through policy, authorization, and audit layers.
- Give the AI agent access only through explicit application tools.
- Support durable asynchronous operations.
- Prevent a monolithic implementation where Next.js UI code directly calls Microsoft Graph, Gmail, or iCloud.
This is a logical API specification.
It does not prescribe final URL naming, framework routing structure, or transport implementation.
2. Core API Principle
The platform should expose an application API that represents the Inbox Agent domain.
Clients should request:
Archive this conversation
Show what needs my attention
Create a draft
Explain this classification
Search for receipts
Approve this rule
Clients should not request:
PATCH this Microsoft Graph message
Modify this Gmail label directly
Issue this IMAP MOVE command
Provider mechanics belong behind the application layer.
3. High-Level Service Model
Recommended logical services:
Client Applications
│
▼
Application API
│
├── Mail Query Service
├── Conversation Service
├── Attention Service
├── Search Service
├── Rule Service
├── Learning Service
├── Approval Service
├── Command Service
├── Agent Service
├── Migration Service
├── Account / Identity Service
├── Provider Health Service
└── Future Contact Service
│
▼
Domain Layer
│
▼
Provider Adapter Layer
4. Client Types
The API should be capable of serving:
Web Application
Native iOS Application
Administrative Tools
Background Workers
Agent Tool Gateway
Future Automation Clients
The API contract should not assume React or Next.js is the only consumer.
5. API Style
A typed HTTP API is recommended for client/server communication.
Possible implementation approaches include:
REST
Typed RPC
GraphQL
The exact transport may remain an implementation decision.
The more important requirement is that:
Domain contracts are explicit and versionable.
A mixed strategy is acceptable, for example:
Typed internal service interfaces
+
HTTP JSON API for clients
6. API Versioning
External client-facing APIs should support versioning.
Example conceptual namespace:
/api/v1/
Breaking contract changes should not silently invalidate older iOS clients.
This becomes particularly important once a native mobile application exists.
7. Authentication
Every user-facing API request must execute within an authenticated application session.
The application API is distinct from provider OAuth authorization.
Two separate concepts:
Inbox Agent Authentication
Who is using the application?
Provider Authorization
Which external mailbox may the platform access?
These must not be conflated.
8. Authorization
Each API operation should evaluate:
Authenticated user
Resource ownership
Action authorization
Automation policy
Provider capability
Approval requirements
A successful login alone must not grant unrestricted provider mutation rights.
9. API Response Envelope
A consistent response model is recommended.
Conceptually:
{
"data": {},
"meta": {},
"error": null
}
For failure:
{
"data": null,
"error": {
"code": "PROVIDER_UNAVAILABLE",
"message": "Gmail is temporarily unavailable.",
"retryable": true
}
}
Do not expose raw provider errors directly to clients.
10. Error Contract
Standard application error classes should include:
UNAUTHENTICATED
UNAUTHORIZED
NOT_FOUND
VALIDATION_ERROR
CONFLICT
APPROVAL_REQUIRED
POLICY_DENIED
PROVIDER_UNAVAILABLE
PROVIDER_AUTH_EXPIRED
RATE_LIMITED
STALE_DATA
COMMAND_FAILED
SYNC_REQUIRED
MIGRATION_CONFLICT
INTERNAL_ERROR
Provider-specific errors should map into these canonical types.
11. Correlation IDs
Every API request that can trigger downstream processing should receive a correlation ID.
Clients may display or log it for troubleshooting.
The same ID should follow:
API Request
→ Command
→ Provider Adapter
→ Audit Event
→ Background Job
12. Read vs Write Separation
The API should distinguish:
Queries
from:
Commands
Queries retrieve state and should not cause mailbox mutations.
Commands represent requested changes.
This is especially important for agent-driven operations.
13. Query Service
The Mail Query Service should provide read-only access to normalized mail data.
Responsibilities:
List messages
Retrieve message
Retrieve conversation
List folders
Retrieve mailbox metadata
Retrieve classifications
Retrieve attachment metadata
It must not directly perform provider mutation.
14. Home Summary Contract
Example logical request:
GET HomeSummary
Response should include:
needs_action_count
respond_count
waiting_count
system_alert_count
important_new_count
read_later_count
processed_quietly_count
provider_health_summary
Each count should support drill-down to the exact underlying records.
15. Needs Me Query
Logical request:
GetNeedsMe
Supported filters:
mailbox
identity
attention_state
priority
classification
sender
project
age
due_date
Response items should include:
conversation_id
message_id
sender
subject
summary
attention_state
priority
reason_summary
received_at
mailbox
delivered_identity
due_at
16. Respond Query
Logical request:
GetRespondQueue
Response:
conversation_id
sender
subject
request_summary
priority
received_at
age
mailbox
sending_identity
17. Waiting Query
Logical request:
GetWaitingQueue
Response should include:
conversation_id
waiting_on
reason
started_at
expected_response_at
follow_up_after
age
priority
status
18. System Alert Query
Logical request:
GetSystemAlerts
Useful filters:
provider/service
project
severity
status
date
System alerts should expose parsed operational metadata where available.
Example:
source = Vercel
project = PocketSomm
event_type = DEPLOYMENT
status = FAILED
environment = PRODUCTION
19. Conversation Service
The Conversation Service should provide the canonical working view of a thread.
Logical request:
GetConversation(conversation_id)
Response should include:
conversation
participants
messages
attention_state
priority
classification
waiting_state
action_state
agent_summary
related_project
available_actions
20. Available Actions
The service should calculate which actions are currently valid.
Example:
can_archive
can_mark_done
can_move_to_waiting
can_create_draft
can_send
can_delete
requires_send_approval
requires_delete_approval
Clients should not independently infer authorization policy.
21. Message Content Retrieval
Full body retrieval may be separate from ordinary message metadata.
Example logical operation:
GetMessageContent(message_id)
The backend may:
Return cached content
Fetch provider content
Refresh stale cache
The client should not need to know which.
22. Attachment Contract
Logical operations:
ListAttachments(message_id)
GetAttachmentMetadata(attachment_id)
RequestAttachmentDownload(attachment_id)
The API should return a controlled download mechanism rather than exposing provider credentials or internal attachment endpoints.
23. Search Service
Search should support:
Structured search
Natural-language search
Hybrid search
Historical search
24. Structured Search Contract
Example criteria:
sender
recipient
original_recipient
subject
date_from
date_to
mail_account
identity
classification
attention_state
priority
project
has_attachment
historical
source_provider
original_folder
Search response should indicate where each result came from.
25. Natural-Language Search
Logical request:
SearchNaturalLanguage("receipt for my monitor last year")
The service should:
Interpret query
Generate structured criteria
Search available indexes/providers
Return results
Return interpreted criteria
The user should be able to inspect the interpretation.
26. Search Plan
A search result may include metadata:
interpreted_query
providers_searched
local_index_searched
provider_search_used
partial_results
stale_sources
This is especially useful if one provider is unavailable.
27. Natural-Language Command Service
Natural-language action requests should be distinct from natural-language search.
Example:
Archive successful Vercel notifications from this week.
Pipeline:
User request
→ Intent parsing
→ Proposed structured command
→ Match discovery
→ Policy evaluation
→ Preview / approval if required
→ Durable command execution
28. Command Preview Contract
Before executing broad mutations, clients should be able to request a preview.
Example response:
command_type
matched_count
mailboxes_affected
sample_items
risk_level
approval_required
estimated_batches
29. Command Service
All mailbox mutation operations should go through the Command Service.
Supported logical commands:
MarkRead
MarkUnread
Archive
Move
SetPriority
SetAttention
SetClassification
AssignProject
ApplyLabel
ApplyCategory
CreateDraft
SendDraft
Delete
30. Command Lifecycle
Commands should use durable state.
PENDING
AUTHORIZED
QUEUED
RUNNING
SUCCEEDED
PARTIALLY_SUCCEEDED
FAILED
CANCELLED
31. Command Submission
Logical request:
SubmitCommand
should contain:
command_type
target_type
target_ids
parameters
requested_by
idempotency_key
The client should not provide provider-specific identifiers unless the operation is explicitly provider administrative.
32. Command Result
Response should include:
command_id
status
approval_required
approval_id
affected_count
correlation_id
For asynchronous commands:
status = QUEUED
The client can later query command status.
33. Command Status
Logical request:
GetCommandStatus(command_id)
Response:
status
processed_count
total_count
success_count
failure_count
started_at
completed_at
errors
34. Idempotency
Mutation endpoints must support idempotency.
Example:
A mobile client submits Archive twice because of a network retry.
Result:
One logical archive operation
not two independent actions.
35. Optimistic UI
Clients may update presentation optimistically for low-risk operations.
However, the application should return a durable command ID so the client can reconcile final state.
If provider execution fails, the UI must restore or correct its state.
36. Approval Service
High-risk operations should route through Approval Service.
Logical operations:
ListPendingApprovals
GetApproval
Approve
Reject
ModifyProposal
37. Approval Response
Approval detail should include:
approval_type
risk_level
reason
affected_count
sample
requested_action
requested_by
expiration
Approval should not require exposing internal provider payloads.
38. Approval and Execution Separation
Approving an action changes:
Authorization state
It does not itself imply successful provider execution.
The execution result must still be tracked separately.
39. Rule Service
Rule API responsibilities:
List rules
Get rule
Create rule
Update rule
Test rule
Activate rule
Pause rule
Retire rule
Rollback rule version
Get rule history
Get rule health
40. Rule Test Contract
Logical request:
TestRule(rule_definition, historical_window)
Response:
matched_count
sample_matches
possible_exceptions
mailboxes_affected
estimated_monthly_volume
risk_level
conflicts
shadowed_rules
No provider mutations should occur during testing.
41. Rule Conflict Contract
Before activation, Rule Service should return:
conflicting_rules
shadowed_rules
precedence_result
The UI should not have to reproduce conflict logic.
42. Rule Suggestion Service
Learning-generated suggestions should be retrievable separately from active rules.
Logical operations:
ListRuleSuggestions
GetRuleSuggestion
ApproveSuggestion
ModifySuggestion
RejectSuggestion
SuppressSuggestion
43. Learning Service
Learning Service should expose read access to:
Corrections
Learned preferences
Pattern observations
Sender profiles
Suggestion history
User corrections should be submitted through explicit operations.
44. Correction Contract
Logical request:
CorrectClassification
CorrectPriority
CorrectAttentionState
CorrectProject
CorrectIdentityRecommendation
Request:
target_id
old_value
new_value
reason_optional
The service should:
Update current state
Record correction
Trigger learning observation
Audit the correction
45. Preference Service
Soft learned preferences should be inspectable and manageable.
Operations:
ListPreferences
UpdatePreference
DisablePreference
DeletePreference
Deleting a preference should not delete historical corrections that produced it.
46. Agent Service
The Agent Service should expose conversational and task-oriented reasoning functions.
Logical operations:
AskAgent
SummarizeMessage
SummarizeConversation
DraftReply
ExplainDecision
SuggestNextAction
47. Agent Request Context
The client may provide:
conversation_id
message_id
current_view
user_question
The backend should retrieve authoritative context itself.
Clients should not send large reconstructed email histories unless explicitly required.
48. Agent Response Contract
Agent responses should support structured references.
Example:
answer
referenced_messages[]
referenced_conversations[]
suggested_actions[]
requires_approval
Every referenced mail item should be directly openable.
49. Agent Tool Boundary
The Agent Service must not directly call provider adapters for unrestricted mutations.
Instead:
Agent
→ Application Tool
→ Policy
→ Command Service
→ Provider Adapter
50. Agent Read Tools
Allowed read-oriented tools may include:
search_messages
get_message
get_conversation
get_waiting_items
get_sender_profile
get_rules
get_calendar_context_future
51. Agent Mutation Tools
Mutation tools should represent requests rather than raw provider operations.
Example:
request_archive
request_move
request_create_draft
request_mark_done
request_change_priority
The tool result may be:
EXECUTED
APPROVAL_REQUIRED
DENIED
52. Explainability Service
A dedicated logical operation should support:
Explain(message_id, field_or_action)
Examples:
Why is this HIGH?
Why is this RESPOND?
Why was this archived?
Why is Gmail recommended for this sender?
Response should provide concise evidence.
It should not expose private model chain-of-thought.
53. Draft Service
Logical operations:
GenerateDraft
GetDraft
UpdateDraft
SaveDraftToProvider
DiscardDraft
RequestSend
54. Generate Draft Request
Inputs may include:
conversation_id
from_identity_id
tone_optional
special_instruction_optional
The server should obtain the relevant thread context itself.
55. Draft Response
Response:
draft_id
from_identity
to
cc
subject
body
source = AI
provider_saved = false
The UI must distinguish an application suggestion from a provider-native saved draft.
56. Draft Save
Saving to provider should go through the Command Service.
The resulting provider draft ID should be stored only after successful provider creation.
57. Send Contract
Sending should require:
Valid draft
Explicit from identity
Resolved recipients
Current send policy
Approval if required
Initial policy should require user approval.
58. Account Service
Account Service should manage application-side mailbox configuration.
Operations:
ListAccounts
GetAccount
ConnectAccount
DisconnectAccount
UpdateMailboxRole
SetOperatingMode
ListIdentities
AddAliasMetadata
RetireIdentity
Actual OAuth flows may use dedicated authorization endpoints.
59. Provider Authorization Contract
Provider connection flow should conceptually support:
StartAuthorization
HandleAuthorizationCallback
GetAuthorizationStatus
RevokeAuthorization
Provider credentials should never be returned to the client.
60. Identity Service
Identity API should support:
ListIdentities
GetIdentity
UpdateIdentityPurpose
SetPrimaryIdentity
MarkAlias
SetIdentityActive
It should not imply creation of an actual email alias at the provider unless that capability is explicitly implemented.
61. Identity Hygiene Service
Logical operations:
ListRecommendations
GetRecommendation
AcceptRecommendation
RejectRecommendation
SuppressRecommendation
Accepting a recommendation initially changes Inbox Agent state only.
It should not automatically alter external service account credentials.
62. Provider Health Service
Logical request:
GetProviderHealth
Response per account:
authorization_status
sync_status
last_successful_sync
last_error
push_status
subscription_expiration
backlog
stale
63. Health Detail
Administrative clients may request:
GetProviderDiagnostics(account_id)
This can include:
rate_limit_state
sync_checkpoint
last_webhook
subscription_id
recent_errors
Sensitive tokens must never be returned.
64. Sync Service
Provider synchronization should generally be initiated internally.
Administrative operations may include:
RequestSync
RequestFullResync
PauseSync
ResumeSync
A full resync should be treated as a durable background job.
65. Webhook Boundary
Provider webhooks should terminate at dedicated server-side endpoints.
Examples:
Microsoft notification endpoint
Gmail Pub/Sub receiver
These endpoints should:
Validate
Acknowledge quickly
Enqueue durable processing
They should not perform large classification pipelines synchronously.
66. Internal Event Contract
Provider events should be normalized into internal events.
Example:
{
"event_type": "MAIL_CHANGED",
"mail_account_id": "...",
"provider": "MICROSOFT",
"provider_reference": "...",
"received_at": "...",
"correlation_id": "..."
}
67. Internal Events vs Public APIs
Internal event contracts may evolve faster than public client APIs.
They should still be versioned enough to support durable queued work.
68. Migration Service
Migration operations:
InventorySource
AnalyzeFolders
AnalyzeDuplicates
CreateMigrationPlan
RunDryRun
RunPilot
StartMigration
PauseMigration
ResumeMigration
ReconcileMigration
GetMigrationStatus
69. Migration Inventory Contract
Response should include:
folder_count
message_count
estimated_size
date_range
attachment_count
duplicate_estimate
forwarded_duplicate_estimate
70. Migration Plan
A migration plan should expose:
source_account
target_account
folder_mappings
routing_rules
duplicate_policy
historical_attention_policy
estimated_count
warnings
71. Dry Run Contract
Dry run response:
eligible
skipped
duplicates
conflicts
routing_distribution
estimated_target_volume
warnings
No mutations.
72. Migration Run Contract
Starting a migration should return:
migration_run_id
job_id
status
estimated_items
Progress should be queryable separately.
73. Reconciliation Contract
Reconciliation response:
source_count
target_count
success_count
duplicate_count
conflict_count
failed_count
unresolved_count
integrity_checks
A migration should not be marked complete if unresolved failures remain hidden.
74. Audit Service
Operations:
ListActivity
ListAuditEvents
GetAuditEvent
GetCorrelationTrace
RequestUndo
75. Activity vs Audit
ListActivity should return user-friendly events.
ListAuditEvents may expose more technical detail.
Both should reference the same underlying source of truth.
76. Undo Contract
Logical operation:
RequestUndo(audit_event_id)
Response:
undo_supported
undo_command_id
reason_if_not_supported
Undo itself should use a durable command.
77. Bulk Operations
Bulk APIs should take explicit target sets or a resolved query snapshot.
Avoid:
Archive whatever currently matches this broad query while processing
if the result set can shift during execution.
Preferred:
Resolve target IDs
→ Preview
→ Execute stable batch
78. Batch Snapshot
For large operations, create:
BatchSelection
with:
selection_id
query
resolved_count
resolved_at
expires_at
This makes previews reproducible.
79. Pagination
All potentially large collection endpoints should support cursor-based pagination where practical.
Examples:
Messages
Audit events
Search results
Migration items
Rule executions
Avoid offset pagination for very large changing datasets where it can lead to duplicates or skips.
80. Sorting
Client-facing list APIs should support domain-relevant sort orders.
Examples:
priority
due_at
received_at
waiting_age
last_activity
The backend should define valid sort fields rather than accept arbitrary SQL-like expressions.
81. Filtering
Filtering should use typed query parameters or structured request bodies.
Do not expose direct query-language access to application databases.
82. Field Selection
Clients may eventually benefit from selective response shapes, but premature arbitrary field projection is not required.
Use purpose-built DTOs for major screens first.
83. API DTOs
Client-facing DTOs should not expose persistence entities directly.
Examples:
MessageSummaryDTO
ConversationDetailDTO
NeedsMeItemDTO
RuleSummaryDTO
ProviderHealthDTO
This allows database evolution without breaking clients.
84. Domain Entity Leakage
Avoid returning fields such as:
credential_reference
raw_provider_payload
internal_retry_count
encrypted_secret_id
through normal user APIs.
85. Capability-Driven UI
Provider/account capability information should be surfaced through normalized DTOs.
Example:
can_archive = true
can_create_draft = true
can_send = false
can_move = true
The UI should render based on application capabilities rather than provider-name conditionals.
86. Future iOS Client Contract
The future native iOS client should be able to perform all core workflows through the same application API.
Required mobile-capable functions:
Get dashboard
List Needs Me
Read conversation
Search
Create/edit draft
Approve action
Archive
Mark Done
Move to Waiting
Review System Alerts
Receive push notification targets
No iOS feature should require direct Graph/Gmail credentials on the device unless a future security review explicitly chooses that model.
87. Push Notification Contract
The backend should generate application-level notification events.
Example:
notification_id
type
priority
title
summary
conversation_id
deep_link_target
created_at
A mobile push provider may then deliver these.
88. Deep Links
API resources should map cleanly to stable client routes/deep links.
Examples:
conversation/{id}
approval/{id}
rule/{id}
system-alert/{id}
This supports web and iOS notifications.
89. Future Contact Service
The API should reserve an independent contact domain.
Potential future operations:
ListPeople
SearchPeople
GetPerson
ListContactSources
ListMergeCandidates
MergePeople
SplitPerson
UpdatePreferredField
SyncContacts
Contact APIs should not be buried inside mail endpoints.
90. Person Reference
Mail APIs should eventually return:
person_id
when a sender/recipient has been resolved to a canonical Person.
Until then:
person_id = null
is valid.
91. Calendar Context Service
Calendar should remain contextual rather than a full calendar-management API.
Potential future operations:
FindRelatedEvents
GetAvailabilityContext
LinkConversationToEvent
No requirement exists to build full calendar CRUD while Fantastical remains the preferred user interface.
92. Provider Adapter Contract
Each adapter should implement a common internal interface.
Conceptual functions:
get_account_profile
list_folders
get_message
list_messages
get_thread
search_messages
get_changes
archive
move
mark_read
apply_metadata
create_draft
send
delete
subscribe
renew_subscription
Unsupported capabilities should fail predictably with:
CAPABILITY_NOT_SUPPORTED
93. Provider Adapter Return Types
Provider adapters should return canonical internal result models, not raw provider payloads.
Example:
ProviderMessageResult
ProviderMutationResult
ProviderSyncResult
ProviderSubscriptionResult
Raw payloads may be retained internally for debugging or migration when appropriate.
94. Provider Mutation Result
Example:
success
provider_message_id
provider_immutable_id
new_folder_id
provider_timestamp
warnings
The Command Service then updates canonical application state.
95. Provider Capability Registry
The backend should be able to ask:
What can this specific account currently do?
rather than assume all Microsoft or Gmail accounts have identical permissions.
Capabilities depend on:
Provider
Granted scopes
Account type
Operating mode
Feature configuration
96. Rate-Limit Isolation
Clients and agent tools should not call provider adapters directly.
This allows centralized:
Rate limiting
Batching
Retry
Concurrency management
97. Agent Tool API
Agent tools should be narrower than the general backend API.
Example tool set:
search_mail
read_conversation
get_attention_items
get_waiting_items
get_sender_context
propose_rule
test_rule
request_archive
request_mark_done
request_draft
request_waiting
explain_message
98. Tool Contract Safety
Tool definitions should be:
Typed
Schema-validated
Narrowly scoped
Auditable
Policy-controlled
Free-form model output should never map directly to SQL, provider API calls, or arbitrary URLs.
99. Agent Query Limits
Agent searches should use configurable limits.
The agent should not fetch thousands of full email bodies merely because a broad question was asked.
Pattern:
Search metadata
→ narrow result set
→ fetch relevant content
→ answer
100. Context Retrieval
When generating a response or classification, backend context retrieval should select only relevant:
Current message
Relevant thread messages
Sender context
Approved rules
Learned preferences
Project context
Avoid dumping unrelated mailbox history into the model.
101. Model Gateway Contract
AI functions should go through a model gateway.
Logical operations:
classify
summarize
extract
draft
interpret_query
recommend_rule
Inputs and outputs should be schema-defined.
102. Model Metadata
Each model response should retain:
provider
model
model_version
prompt_version
latency
usage
structured_output_valid
Cost metadata may also be retained where available.
103. Model Failure
The API should map model failure to application behavior.
Example:
AI_UNAVAILABLE
should not fail ordinary deterministic archive rules.
104. Staleness Contract
Read APIs should indicate stale data where appropriate.
Example:
data_freshness:
current
stale
unknown
plus:
last_successful_sync
105. Partial Results
Cross-provider operations may return partial results.
Example:
Microsoft searched successfully
Gmail unavailable
iCloud searched successfully
Response should explicitly indicate partial completeness.
106. Concurrency Conflicts
If a client edits stale state:
Example:
Web says RESPOND
iOS already marked DONE
the API should return a conflict rather than silently overwriting newer state where correctness matters.
Version fields or updated timestamps may support optimistic concurrency.
107. Resource Versioning
Mutable resources may expose:
version
updated_at
Clients may submit:
expected_version
for critical updates.
108. Provider-State Reconciliation
The API should distinguish:
Application state update
Provider mutation
Provider reconciliation
Example:
Changing attention state may be purely application-local.
Archiving requires provider mutation.
109. Local-Only Actions
Examples of application-local actions:
Set attention state
Set project
Set priority
Create learned preference
Dismiss identity recommendation
These should not unnecessarily call provider APIs.
110. Provider Actions
Examples requiring provider mutation:
Archive message
Move message
Mark read
Create provider draft
Send
Delete
Apply provider label/category
111. Eventual Consistency
Clients must tolerate a short interval where:
Command accepted
but:
Provider state not yet confirmed
The UI can display:
Archiving...
until command completion.
112. Offline Mobile Behavior
A future iOS client may cache read models.
Offline mutation behavior should eventually support:
Queue local command
Sync when online
Resolve conflicts
This is not required for the first web release but should not be architecturally blocked.
113. API Security
All API endpoints must enforce:
TLS
Authenticated session
CSRF protection where relevant
Input validation
Rate limiting
Authorization
Audit logging for sensitive operations
114. Sensitive Endpoints
Higher-risk endpoints should receive additional controls.
Examples:
Send
Delete
Provider disconnect
OAuth scope escalation
Bulk migration cleanup
Potential controls:
Recent authentication
Explicit confirmation
Approval
Rate limits
115. No Secret Echoing
No API response should return:
OAuth refresh token
App-specific password
Provider secret
Webhook secret
Encryption key
even to administrative UI.
116. API Logging
Request logging should avoid:
Full message bodies
Authorization headers
Raw attachment content
OAuth callbacks containing credentials
Log resource IDs and correlation IDs instead.
117. Auditability
Any endpoint that changes durable state should identify:
actor
resource
action
timestamp
correlation_id
and create an audit event where appropriate.
118. Client Telemetry
Clients may submit non-sensitive UX telemetry such as:
screen opened
rule suggestion reviewed
draft accepted
undo clicked
Telemetry should not contain email content unless explicitly required.
119. API Documentation
The service contracts should generate or maintain machine-readable API documentation.
Preferred:
OpenAPI
for HTTP APIs or equivalent schema tooling.
This helps:
Cursor
Charter-generated implementation work
Native iOS client generation
Contract testing
120. Generated Client Libraries
Once the API stabilizes, typed clients should be generated where practical.
Potential clients:
TypeScript
Swift
This reduces drift between the web backend and future iOS implementation.
121. Contract Testing
Provider adapters and client APIs should have contract tests.
Examples:
Microsoft adapter returns canonical Message
Gmail adapter returns same canonical semantics
Unsupported operation returns standard error
Command requiring approval never executes directly
122. API Mocking
A mock application API should support UI development without live mailboxes.
Synthetic responses should cover:
Needs Me
Respond
Waiting
System Alerts
Search
Approvals
Rule suggestions
Provider failure
Migration progress
123. API Acceptance Criteria
The API architecture is acceptable when:
- Web clients do not directly call Microsoft Graph, Gmail, or iCloud.
- A future iOS client can use the same application services.
- Queries and mailbox mutations are clearly separated.
- All provider mutations use durable commands.
- High-risk commands route through policy and approval.
- Provider-specific IDs do not leak unnecessarily into clients.
- Provider capabilities are normalized.
- Natural-language commands resolve into structured application commands.
- The AI agent only uses explicit, policy-controlled tools.
- Cross-provider queries can report partial or stale results.
- Provider outages do not invalidate unrelated providers.
- Rule testing is non-mutating.
- Migration runs are asynchronous and observable.
- All important operations support audit correlation.
- API contracts are versionable.
- Future contacts can be added as an independent domain.
- Calendar context can be added without turning the platform into a calendar application.
124. Core Service Boundary Principle
The architecture should enforce:
CLIENT
asks what the user wants
APPLICATION SERVICE
understands the domain operation
POLICY
decides whether it is allowed
COMMAND
records what should happen
PROVIDER ADAPTER
knows how to do it externally
AUDIT
records what happened
AGENT
may request operations but does not bypass any layer
This boundary is fundamental to keeping the Inbox Agent safe, testable, portable, and capable of supporting both web and native clients.
