{"openapi":"3.1.0","info":{"title":"CallTracker API","version":"1.0.0","description":"Read-only access to calls, placements and tracking numbers in one CallTracker workspace. Authenticate with a workspace API key ('Authorization: Bearer ct_live_…'). Each key is limited to 120 requests per minute."},"servers":[{"url":"https://calltracker.dev/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Workspace API key created in Settings → API access. Scopes: calls:read, placements:read, numbers:read."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["unauthorized","insufficient_scope","rate_limited","invalid_request","not_found"]},"message":{"type":"string"}}}}},"Attribution":{"type":"object","properties":{"trafficSource":{"type":["string","null"]},"utmSource":{"type":["string","null"]},"utmMedium":{"type":["string","null"]},"utmCampaign":{"type":["string","null"]},"utmTerm":{"type":["string","null"]},"utmContent":{"type":["string","null"]},"gclid":{"type":["string","null"]},"gbraid":{"type":["string","null"]},"wbraid":{"type":["string","null"]},"fbclid":{"type":["string","null"]},"msclkid":{"type":["string","null"]},"referrerUrl":{"type":["string","null"]},"landingPage":{"type":["string","null"]}}},"Call":{"type":"object","required":["id","placementId","callerNumber","status","durationSeconds","startedAt"],"properties":{"id":{"type":"string"},"placementId":{"type":"string"},"callerNumber":{"type":"string","description":"E.164"},"status":{"type":"string"},"durationSeconds":{"type":"integer"},"connectedSeconds":{"type":"integer"},"aiHandled":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"hasRecording":{"type":"boolean"},"transcriptionStatus":{"type":["string","null"]},"startedAt":{"type":"string","format":"date-time"},"attribution":{"$ref":"#/components/schemas/Attribution"},"googleAdsUploadStatus":{"type":["string","null"],"enum":["pending","uploaded","failed","skipped",null]}}},"Placement":{"type":"object","required":["id","name","active","createdAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"trackingNumber":{"type":["string","null"]},"countryCode":{"type":"string"},"active":{"type":"boolean"},"dynamicNumberInsertion":{"type":"boolean"},"recordingEnabled":{"type":"boolean"},"transcriptionEnabled":{"type":"boolean"},"monthlyCost":{"type":["object","null"],"properties":{"amount":{"type":"number"},"currency":{"type":"string"}}},"createdAt":{"type":"string","format":"date-time"}}},"TrackingNumber":{"type":"object","required":["phoneNumber","type","placementId","active"],"properties":{"phoneNumber":{"type":"string"},"type":{"type":"string","enum":["placement","pool"]},"placementId":{"type":"string"},"poolId":{"type":["string","null"]},"trafficSource":{"type":["string","null"]},"countryCode":{"type":"string"},"active":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}}}},"paths":{"/calls":{"get":{"summary":"List calls","description":"Newest first. Requires the calls:read scope.","parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Calls started at or after this time."},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Calls started before this time."},{"name":"placementId","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["ringing","in-progress","completed","missed","busy","failed","no-answer","canceled"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of calls.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Call"}},"nextCursor":{"type":["string","null"]}}}}}},"400":{"description":"Invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/calls/{id}":{"get":{"summary":"Get a call","description":"Requires the calls:read scope.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The call.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Call"}}}}}},"400":{"description":"Invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No call with that ID in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/placements":{"get":{"summary":"List placements","description":"Newest first. Requires the placements:read scope.","parameters":[{"name":"active","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of placements.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Placement"}},"nextCursor":{"type":["string","null"]}}}}}},"400":{"description":"Invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers":{"get":{"summary":"List tracking numbers","description":"Single placement numbers and dynamic number insertion pool numbers. Requires the numbers:read scope.","parameters":[{"name":"placementId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"All tracking numbers (up to 1000 of each type).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TrackingNumber"}},"truncated":{"type":"boolean"}}}}}},"400":{"description":"Invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}