{"openapi":"3.1.0","info":{"title":"Northsun public API","version":"v1","description":"Northsun is the memory and enrichment layer for AI agents. Every agent proposes. Northsun governs. The public v1 API is these three routes."},"servers":[{"url":"https://mcp.northsun.ai"}],"security":[{"bearerAuth":[]}],"paths":{"/v1/recall_and_enrich":{"post":{"operationId":"recallAndEnrich","summary":"Voice-entry caller memory recall and enrichment.","description":"Call once before the agent speaks. Returns the caller profile, memory of recent calls and the Trestle and Twilio Lookup enrichment that was available. A number Northsun has not seen before comes back as known: false, not as an error; a failed caller read comes back as known: false with degraded: true.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phone_number":{"type":"string","minLength":1},"agent_id":{"type":"string"},"trigger":{"type":"string","enum":["ringing","answered"]},"session_id":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}},"required":["phone_number"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecallAndEnrichResponse"}}}},"400":{"description":"The request could not be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key is not allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"The request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/calls/end":{"post":{"operationId":"callsEnd","summary":"End a voice call and persist its memory write-back.","description":"Call once after hangup to write the conversation back: transcript, duration and outcome. Northsun answers 204 when it accepts the write.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"session_id":{"type":"string","minLength":1},"phone_number":{"type":"string","minLength":1},"transcript":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["user","agent"]},"text":{"type":"string"},"ts_ms":{"type":"number"}},"required":["role","text","ts_ms"]}},"duration_s":{"type":"number","minimum":0},"outcome":{"$ref":"#/components/schemas/CallOutcome"},"agent_metadata":{"type":"object","additionalProperties":true}},"required":["session_id","phone_number","transcript","duration_s","outcome"]}}}},"responses":{"204":{"description":"Recorded; empty body."},"400":{"description":"The request could not be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key is not allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"The request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/caller/{phone_number}":{"get":{"operationId":"getCaller","summary":"Read-only caller profile lookup by phone number.","description":"Read a caller profile outside a live call, to verify that a write landed.","parameters":[{"name":"phone_number","in":"path","required":true,"description":"Caller phone number in E.164 format.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Caller"}}}},"400":{"description":"The request could not be read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key is not allowed to do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Northsun has no such caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"The request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A tenant API key, sent as `Authorization: Bearer <key>`."}},"schemas":{"Caller":{"type":"object","properties":{"name":{"type":["string","null"]},"first_seen_ms":{"type":["number","null"]},"last_seen_ms":{"type":["number","null"]},"total_calls":{"type":["integer","null"],"description":"null means unknown, never zero."},"tags":{"type":"array","items":{"type":"string"}},"custom_attributes":{"type":"object","additionalProperties":true}},"required":["name","first_seen_ms","last_seen_ms","total_calls","tags","custom_attributes"],"additionalProperties":false},"CallOutcome":{"type":"string","enum":["appointment_booked","quote_given","callback_requested","no_answer","other"]},"RecallAndEnrichResponse":{"type":"object","properties":{"trace_id":{"type":"string"},"known":{"type":"boolean","description":"false for a number Northsun has not seen before. Not an error. Read it together with degraded."},"degraded":{"type":"boolean","const":true,"description":"Present only when Northsun could not read the caller (a degraded 200): every field is then null or empty and known is false. Do not treat it as a first-time caller."},"caller":{"$ref":"#/components/schemas/Caller"},"memory":{"type":"object","properties":{"summary":{"type":"string"},"recent_calls":{"type":"array","maxItems":5,"items":{"type":"object","properties":{"call_id":{"type":"string"},"started_at_ms":{"type":["number","null"]},"duration_s":{"type":"number"},"summary":{"type":"string"},"outcome":{"type":["string","null"]}},"required":["call_id","started_at_ms","duration_s","summary","outcome"],"additionalProperties":true}}},"required":["summary","recent_calls"],"additionalProperties":true},"enrichment":{"type":"object","properties":{"person":{"oneOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"title":{"type":["string","null"]},"company":{"type":["string","null"]}},"required":["name"],"additionalProperties":true},{"type":"null"}]},"company":{"oneOf":[{"type":"object","properties":{"name":{"type":["string","null"]},"address":{}},"required":["name"],"additionalProperties":true},{"type":"null"}]},"phone":{"oneOf":[{"type":"object","properties":{"carrier":{"type":["string","null"]},"line_type":{"type":["string","null"]}},"required":["carrier","line_type"],"additionalProperties":true},{"type":"null"}]}},"required":["person","company","phone"],"additionalProperties":true},"timing_ms":{"type":"object","properties":{"total":{"type":"number"},"memory_ms":{"type":"number"},"enrichment_ms":{"type":"number"},"cache_hit":{"type":"boolean"}},"required":["total","memory_ms","enrichment_ms","cache_hit"],"additionalProperties":true},"freshness":{"type":"object","properties":{"memory_age_ms":{"type":["number","null"]},"enrichment_age_ms":{"type":["number","null"]}},"required":["memory_age_ms","enrichment_age_ms"],"additionalProperties":true}},"required":["trace_id","known","caller","memory","enrichment","timing_ms","freshness"],"additionalProperties":true},"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":true}}}}
