{"openapi":"3.1.0","info":{"title":"Loops (BYOK) API","version":"0.1.0","description":"Loops (BYOK) lets an AI assistant read your own Loops data through the Loops API with a key you supply (API key). Read-only: 7 tools (get_team, list_mailing_lists, list_contact_properties, list_campaigns, get_campaign_metrics, list_workflows, list_transactional_emails). The BYOK key travels with each request, is used for that one call only and is never stored, logged or cached; it is only ever...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-loops.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-loops/docs"},"termsOfService":"https://connectorbay.com/byok-loops/terms"},"servers":[{"url":"https://byok-loops.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-loops/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/get_team":{"post":{"operationId":"get_team","summary":"Check the API key and show the name of the Loops team it belongs to. Use for \"Which Loops team does my API key belong to","description":"Check the API key and show the name of the Loops team it belongs to. Use for \"Which Loops team does my API key belong to\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"get_teamArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_mailing_lists":{"post":{"operationId":"list_mailing_lists","summary":"List the team's mailing lists with ID, name, description and whether each is public. Use for \"What mailing lists do I ha","description":"List the team's mailing lists with ID, name, description and whether each is public. Use for \"What mailing lists do I have in Loops\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_mailing_listsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_contact_properties":{"post":{"operationId":"list_contact_properties","summary":"List contact properties (key, label, type string/number/boolean/date), all or only custom ones. Use for \"Which custom co","description":"List contact properties (key, label, type string/number/boolean/date), all or only custom ones. Use for \"Which custom contact properties are defined in Loops\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"list":{"anyOf":[{"enum":["all","custom"],"type":"string"},{"type":"null"}],"default":"all","description":"Which properties: all (default) or custom.","title":"List"}},"title":"list_contact_propertiesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_campaigns":{"post":{"operationId":"list_campaigns","summary":"List email campaigns with status (Draft, Scheduled, Sending, Sent), schedule and target list. Needs the content API enab","description":"List email campaigns with status (Draft, Scheduled, Sending, Sent), schedule and target list. Needs the content API enabled for the team. Cursor pagination. Use for \"Which Loops campaigns have been sent\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"per_page":{"anyOf":[{"maximum":50,"minimum":10,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (10 to 50, default 20).","title":"Per Page"},"cursor":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: pass pagination.nextCursor from the previous answer.","title":"Cursor"}},"title":"list_campaignsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_campaign_metrics":{"post":{"operationId":"get_campaign_metrics","summary":"Get delivery metrics of a sent campaign: sends, opens, clicks, unsubscribes, spam reports and bounces. Use for \"How did ","description":"Get delivery metrics of a sent campaign: sends, opens, clicks, unsubscribes, spam reports and bounces. Use for \"How did my last Loops campaign perform\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Campaign ID from list_campaigns (campaign must already be sent).","maxLength":200,"title":"Campaign Id","type":"string"}},"required":["campaign_id"],"title":"get_campaign_metricsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_workflows":{"post":{"operationId":"list_workflows","summary":"List automation workflows (loops) with ID, name, creation and update times. Needs the content API enabled for the team. ","description":"List automation workflows (loops) with ID, name, creation and update times. Needs the content API enabled for the team. Use for \"What automated workflows do I have in Loops\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"per_page":{"anyOf":[{"maximum":50,"minimum":10,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (10 to 50, default 20).","title":"Per Page"},"cursor":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: pass pagination.nextCursor from the previous answer.","title":"Cursor"}},"title":"list_workflowsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_transactional_emails":{"post":{"operationId":"list_transactional_emails","summary":"List transactional email templates with ID, name, group, data variables and update time, newest first. Use for \"Which tr","description":"List transactional email templates with ID, name, group, data variables and update time, newest first. Use for \"Which transactional emails exist in Loops and what variables do they take\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"per_page":{"anyOf":[{"maximum":50,"minimum":10,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (10 to 50, default 20).","title":"Per Page"},"cursor":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: pass pagination.nextCursor from the previous answer.","title":"Cursor"}},"title":"list_transactional_emailsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}