{"openapi":"3.1.1","info":{"title":"NotFair API and MCP Reference","version":"1.0.0","description":"Public discovery and the existing NotFair Streamable HTTP MCP API for advertising, search, analytics, CRM, and WordPress integrations. Tool operations require a workspace OAuth bearer token. This is a JSON-RPC MCP API, not a REST facade for individual platform operations. Connect an MCP client for initialization, authentication, tool discovery and execution. Platform access depends on connected accounts, permissions and enabled integrations.","contact":{"name":"NotFair support","url":"https://notfair.co/contact","email":"tong@notfair.co"}},"servers":[{"url":"https://notfair.co","description":"Canonical NotFair origin"},{"url":"https://www.notfair.co","description":"Supported legacy OAuth/MCP origin; discover OAuth metadata on the same origin you connect to."}],"externalDocs":{"description":"NotFair API documentation and examples","url":"https://notfair.co/docs/reference/api"},"paths":{"/api/health":{"get":{"operationId":"getNotFairHealth","summary":"Check NotFair HTTP availability","description":"Returns an application heartbeat and current UTC timestamp. This is not a check of upstream platform credentials or service health.","security":[],"responses":{"200":{"description":"Application is responding.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"ts":{"type":"string","format":"date-time"}},"required":["ok","ts"]}}}}}}},"/.well-known/mcp/server-card.json":{"get":{"operationId":"getNotFairMcpServerCard","summary":"Discover public MCP tool schemas","description":"Returns the generated static metadata for NotFair's canonical compact tools, including input schemas, descriptions and annotations. No customer data is included. Runtime tools/list and tools/call remain authenticated.","security":[],"responses":{"200":{"description":"Static server metadata matching the compact MCP registrar.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerCard"}}}}}}},"/.well-known/oauth-protected-resource/api/mcp/notfair":{"get":{"operationId":"getNotFairProtectedResource","summary":"Discover MCP authorization servers","description":"RFC 9728 metadata for the canonical NotFair MCP resource. Discover authorization server metadata on the returned origin. Preserve that origin through OAuth and validate callback issuer matching exactly.","security":[],"responses":{"200":{"description":"Protected resource metadata.","content":{"application/json":{"schema":{"type":"object","properties":{"resource":{"type":"string","format":"uri"},"authorization_servers":{"type":"array","items":{"type":"string","format":"uri"}},"resource_name":{"type":"string"},"resource_documentation":{"type":"string","format":"uri"},"resource_policy_uri":{"type":"string","format":"uri"},"resource_tos_uri":{"type":"string","format":"uri"},"logo_uri":{"type":"string","format":"uri"}},"required":["resource","authorization_servers","resource_name","resource_documentation","resource_policy_uri","resource_tos_uri","logo_uri"]}}}}}}},"/api/mcp/notfair":{"post":{"operationId":"sendNotFairMcpMessage","summary":"Send a NotFair MCP JSON-RPC message","description":"Send one MCP message per POST using Streamable HTTP. Both application/json and text/event-stream must be accepted. Initialize first and send notifications/initialized before tool calls. Initialization can be anonymous; tools/list and tools/call require OAuth. Use search to discover capabilities, executeRead for returned read capabilities, and execute for supported user-authorized writes. Monthly operation quotas, workspace roles and platform permissions apply; tool failures may return HTTP 200 with isError=true. Never retry a write blindly. Use an MCP SDK to manage the protocol lifecycle and streaming responses.","security":[{"NotFairOAuth":[]}],"parameters":[{"name":"MCP-Protocol-Version","in":"header","required":false,"description":"The version negotiated during initialization; send on subsequent requests.","schema":{"type":"string"},"example":"2025-03-26"},{"name":"Mcp-Session-Id","in":"header","required":false,"description":"Send only if the server assigned a session ID during initialization.","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"A single JSON-RPC request or initialization notification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpRequest"},"examples":{"initialize":{"value":{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"notfair-api-example","version":"1.0.0"}}}},"search":{"value":{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search","arguments":{"query":"list connected accounts"}}}}}}}},"responses":{"200":{"description":"A JSON-RPC response or SSE stream of JSON-RPC messages.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpResponse"}},"text/event-stream":{"schema":{"type":"string","description":"Server-sent events; each message event's data contains an MCP JSON-RPC message."}}}},"202":{"description":"Notification accepted; no response body."},"400":{"description":"Malformed JSON or invalid MCP request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RpcError"}}}},"401":{"description":"Missing, invalid, expired or incorrectly scoped workspace bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}},"headers":{"WWW-Authenticate":{"description":"Bearer challenge with the resource_metadata URL for this request origin.","schema":{"type":"string"}}}},"406":{"description":"Required response media types were not accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RpcError"}}}}}}}},"components":{"securitySchemes":{"NotFairOAuth":{"type":"oauth2","description":"Authorization code with PKCE (S256) and RFC 8707 resource=https://notfair.co/api/mcp/notfair. Discover authorization server metadata at /.well-known/oauth-authorization-server. For www clients, use that origin for discovery, issuer and resource throughout the flow.","flows":{"authorizationCode":{"authorizationUrl":"https://notfair.co/api/oauth/authorize","tokenUrl":"https://notfair.co/api/oauth/token","scopes":{}}}}},"schemas":{"McpRequest":{"oneOf":[{"type":"object","properties":{"jsonrpc":{"const":"2.0","type":"string"},"id":{"type":["string","integer"]},"method":{"const":"initialize","type":"string"},"params":{"type":"object","properties":{"protocolVersion":{"type":"string"},"capabilities":{"type":"object","additionalProperties":true},"clientInfo":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"}},"required":["name","version"]}},"required":["protocolVersion","capabilities","clientInfo"]}},"required":["jsonrpc","id","method","params"]},{"type":"object","properties":{"jsonrpc":{"const":"2.0","type":"string"},"method":{"const":"notifications/initialized","type":"string"}},"required":["jsonrpc","method"]},{"type":"object","properties":{"jsonrpc":{"const":"2.0","type":"string"},"id":{"type":["string","integer"]},"method":{"const":"tools/list","type":"string"}},"required":["jsonrpc","id","method"]},{"type":"object","properties":{"jsonrpc":{"const":"2.0","type":"string"},"id":{"type":["string","integer"]},"method":{"const":"tools/call","type":"string"},"params":{"type":"object","properties":{"name":{"type":"string","const":"search","description":"Discover NotFair capabilities for Google Ads, Meta Ads, X Ads, LinkedIn Ads, Google Analytics, Google Search Console, GoHighLevel, and WordPress. Returns matching capability ids, exact input schemas, safety annotations, the corresponding executor, and the authenticated workspace's connected-platform status."},"arguments":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"query":{"type":"string","minLength":2,"description":"What you need to do, such as 'pause Meta campaign' or 'GA4 key event'."},"platform":{"type":"string","enum":["google_ads","meta_ads","x_ads","linkedin_ads","search_console","google_analytics","gohighlevel","wordpress"]},"workflowId":{"description":"Optional workflow correlation UUID returned by search. Invalid values are safely replaced."}},"required":["query"]}},"required":["name","arguments"]}},"required":["jsonrpc","id","method","params"]},{"type":"object","properties":{"jsonrpc":{"const":"2.0","type":"string"},"id":{"type":["string","integer"]},"method":{"const":"tools/call","type":"string"},"params":{"type":"object","properties":{"name":{"type":"string","const":"executeRead","description":"Execute one NotFair read-only capability by its exact id and validated arguments without changing external state. Contract repairs return a stable error code, safe guidance, and the workflowId to reuse."},"arguments":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"capabilityId":{"type":"string","minLength":1,"description":"Exact read-only capability id returned by search."},"arguments":{"default":{},"description":"Arguments matching the schema returned by search.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"workflowId":{"description":"Optional workflow correlation UUID returned by search. Invalid values are safely replaced."}},"required":["capabilityId"]}},"required":["name","arguments"]}},"required":["jsonrpc","id","method","params"]},{"type":"object","properties":{"jsonrpc":{"const":"2.0","type":"string"},"id":{"type":["string","integer"]},"method":{"const":"tools/call","type":"string"},"params":{"type":"object","properties":{"name":{"type":"string","const":"execute","description":"Execute one NotFair write-capable capability by its exact id and validated arguments through the guarded platform handler. The operation may change external state. Contract repairs return a stable error code, safe guidance, and the workflowId to reuse."},"arguments":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"capabilityId":{"type":"string","minLength":1,"description":"Exact capability id returned by search."},"arguments":{"default":{},"description":"Arguments matching the schema returned by search.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"workflowId":{"description":"Optional workflow correlation UUID returned by search. Invalid values are safely replaced."}},"required":["capabilityId"]}},"required":["name","arguments"]}},"required":["jsonrpc","id","method","params"]}]},"McpResponse":{"oneOf":[{"type":"object","properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","integer"]},"result":{"oneOf":[{"$ref":"#/components/schemas/InitializeResult"},{"$ref":"#/components/schemas/ToolListResult"},{"$ref":"#/components/schemas/CallToolResult"}]}},"required":["jsonrpc","id","result"]},{"$ref":"#/components/schemas/RpcError"}]},"InitializeResult":{"type":"object","properties":{"protocolVersion":{"type":"string"},"capabilities":{"type":"object","additionalProperties":true},"serverInfo":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"}},"required":["name","version"]},"instructions":{"type":"string"}},"required":["protocolVersion","capabilities","serverInfo"]},"ToolListResult":{"type":"object","properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/Tool"}},"nextCursor":{"type":"string"}},"required":["tools"]},"CallToolResult":{"type":"object","properties":{"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","image","audio","resource","resource_link"]},"text":{"type":"string"},"data":{"type":"string"},"mimeType":{"type":"string"},"resource":{"type":"object","additionalProperties":true}},"required":["type"]}},"structuredContent":{"type":"object","additionalProperties":true},"isError":{"type":"boolean"}},"required":["content"]},"RpcError":{"type":"object","properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","integer","null"]},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"},"data":{}},"required":["code","message"]}},"required":["jsonrpc","id","error"]},"Unauthorized":{"type":"object","properties":{"error":{"type":"string"},"oauth":{"type":"object","properties":{"protocol":{"type":"string"},"preferred_flow":{"type":"string"},"authorization_code_pkce":{"type":"boolean"},"resource_metadata":{"type":"string","format":"uri"}},"required":["protocol","preferred_flow","authorization_code_pkce","resource_metadata"]},"fallback":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"label":{"type":"string"},"preferred":{"type":"boolean"}},"required":["url","label","preferred"]}},"required":["error","oauth","fallback"]},"Tool":{"type":"object","properties":{"name":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"inputSchema":{"type":"object","additionalProperties":true},"outputSchema":{"type":"object","additionalProperties":true},"annotations":{"type":"object","properties":{"title":{"type":"string"},"readOnlyHint":{"type":"boolean"},"destructiveHint":{"type":"boolean"},"idempotentHint":{"type":"boolean"},"openWorldHint":{"type":"boolean"}},"required":[]}},"required":["name","inputSchema"]},"ServerCard":{"type":"object","properties":{"serverInfo":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"}},"required":["name","version"]},"authentication":{"type":"object","properties":{"required":{"type":"boolean","const":true},"schemes":{"type":"array","items":{"type":"string","const":"oauth2"}}},"required":["required","schemes"]},"tools":{"type":"array","items":{"$ref":"#/components/schemas/Tool"}},"resources":{"type":"array","items":{"type":"object","properties":{"uri":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"mimeType":{"type":"string"}},"required":["uri","name"]}},"prompts":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"arguments":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"required":{"type":"boolean"}},"required":["name"]}}},"required":["name"]}}},"required":["serverInfo","authentication","tools","resources","prompts"]}}}}