{"openapi":"3.1.0","info":{"title":"AppSignal (BYOK) API","version":"0.1.0","description":"AppSignal (BYOK) lets an AI assistant read your own AppSignal data through the AppSignal API with a key you supply (AppSignal personal API token). Read-only: 10 tools (verify_token, list_error_samples, list_performance_samples, get_sample, list_markers, list_metric_names, get_metric_type_and_tags, query_metric_timeseries, query_metric_by_namespace, get_deploy_statistics). The BYOK key travels...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-appsignal.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-appsignal/docs"},"termsOfService":"https://connectorbay.com/byok-appsignal/terms"},"servers":[{"url":"https://byok-appsignal.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-appsignal/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/verify_token":{"post":{"operationId":"verify_token","summary":"Check that the token works and return the id of the user it belongs to. Use for \"Is my AppSignal API token valid\".","description":"Check that the token works and return the id of the user it belongs to. Use for \"Is my AppSignal API token valid\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"verify_tokenArguments","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_error_samples":{"post":{"operationId":"list_error_samples","summary":"List recent error samples of an app (one per occurrence) with action, path, time, status and exception name. Request par","description":"List recent error samples of an app (one per occurrence) with action, path, time, status and exception name. Request parameters, session data and environment are not returned. Use for \"What errors did my AppSignal app raise today\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"app_id":{"description":"Id of the AppSignal app, the long id in the app's URL (appsignal.com/<organization>/sites/<id>).","maxLength":200,"title":"App Id","type":"string"},"action_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only samples of this action. Replace '#' with '-hash-', '/' with '-slash-' and '.' with '-dot-', so 'BlogPostsController#show' becomes 'BlogPostsController-hash-show'.","title":"Action Id"},"exception":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only samples of this exception class, for example 'NoMethodError'.","title":"Exception"},"since":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Only entries after this time (Unix timestamp in seconds, UTC).","title":"Since"},"before":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Only entries before this time (Unix timestamp in seconds, UTC).","title":"Before"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":10,"description":"How many entries to return (default 10).","title":"Limit"},"count_only":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to return only the number of samples.","title":"Count Only"}},"required":["app_id"],"title":"list_error_samplesArguments","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_performance_samples":{"post":{"operationId":"list_performance_samples","summary":"List recent slow-request samples of an app with action, path, duration, status and time. Use for \"Which requests were sl","description":"List recent slow-request samples of an app with action, path, duration, status and time. Use for \"Which requests were slowest in my AppSignal app\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"app_id":{"description":"Id of the AppSignal app, the long id in the app's URL (appsignal.com/<organization>/sites/<id>).","maxLength":200,"title":"App Id","type":"string"},"action_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only samples of this action. Replace '#' with '-hash-', '/' with '-slash-' and '.' with '-dot-', so 'BlogPostsController#show' becomes 'BlogPostsController-hash-show'.","title":"Action Id"},"since":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Only entries after this time (Unix timestamp in seconds, UTC).","title":"Since"},"before":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Only entries before this time (Unix timestamp in seconds, UTC).","title":"Before"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":10,"description":"How many entries to return (default 10).","title":"Limit"},"count_only":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to return only the number of samples.","title":"Count Only"}},"required":["app_id"],"title":"list_performance_samplesArguments","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_sample":{"post":{"operationId":"get_sample","summary":"Get one error or slow-request sample: action, path, request method, host, timings, exception name, message and backtrace","description":"Get one error or slow-request sample: action, path, request method, host, timings, exception name, message and backtrace. Request parameters, session data, environment and tags are not returned. Use for \"Show the details of AppSignal sample 51f29e7b183d700800150358_SlowController-hash-show_1476962400\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"app_id":{"description":"Id of the AppSignal app, the long id in the app's URL (appsignal.com/<organization>/sites/<id>).","maxLength":200,"title":"App Id","type":"string"},"sample_id":{"description":"Sample id with '#' replaced by '-hash-' (list_error_samples and list_performance_samples return the id).","maxLength":200,"title":"Sample Id","type":"string"}},"required":["app_id","sample_id"],"title":"get_sampleArguments","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_markers":{"post":{"operationId":"list_markers","summary":"List deploy markers and custom markers of an app (when each was created, revision, user, how long it was live, and the e","description":"List deploy markers and custom markers of an app (when each was created, revision, user, how long it was live, and the exception count and rate since). Use for \"Which deploys did my AppSignal app have this week and how did the error rate change\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"app_id":{"description":"Id of the AppSignal app, the long id in the app's URL (appsignal.com/<organization>/sites/<id>).","maxLength":200,"title":"App Id","type":"string"},"kind":{"anyOf":[{"enum":["deploy","custom"],"type":"string"},{"type":"null"}],"default":null,"description":"Only markers of this kind.","title":"Kind"},"from_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Only markers after this time (ISO 8601 or Unix timestamp).","title":"From Time"},"to_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Only markers before this time (ISO 8601 or Unix timestamp).","title":"To Time"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many markers to return.","title":"Limit"},"count_only":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True to return only the number of markers.","title":"Count Only"}},"required":["app_id"],"title":"list_markersArguments","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_metric_names":{"post":{"operationId":"list_metric_names","summary":"List the names of all metrics an app reports, to use in the metric queries. Use for \"Which metrics does my AppSignal app","description":"List the names of all metrics an app reports, to use in the metric queries. Use for \"Which metrics does my AppSignal app report\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"site_id":{"description":"Id of the AppSignal app (site), the id in the app's URL.","maxLength":200,"title":"Site Id","type":"string"}},"required":["site_id"],"title":"list_metric_namesArguments","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_metric_type_and_tags":{"post":{"operationId":"get_metric_type_and_tags","summary":"Get a metric's type (gauge, counter or measurement) and the tag combinations it can be queried with. Use for \"Which tags","description":"Get a metric's type (gauge, counter or measurement) and the tag combinations it can be queried with. Use for \"Which tags can I filter the transaction_duration metric by in AppSignal\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"site_id":{"description":"Id of the AppSignal app (site), the id in the app's URL.","maxLength":200,"title":"Site Id","type":"string"},"metric_name":{"description":"Metric name (list_metric_names returns the names).","maxLength":200,"title":"Metric Name","type":"string"}},"required":["site_id","metric_name"],"title":"get_metric_type_and_tagsArguments","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/query_metric_timeseries":{"post":{"operationId":"query_metric_timeseries","summary":"Get the data points of one metric field over a time range, for example the mean or 95th percentile of request duration p","description":"Get the data points of one metric field over a time range, for example the mean or 95th percentile of request duration per hour, optionally for one namespace (web or background). Use for \"How did the mean response time of my AppSignal app change over the last day\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"site_id":{"description":"Id of the AppSignal app (site), the id in the app's URL.","maxLength":200,"title":"Site Id","type":"string"},"from_time":{"description":"Start of the time range (ISO 8601, for example 2026-10-10T00:00:00Z).","maxLength":200,"title":"From Time","type":"string"},"to_time":{"description":"End of the time range (ISO 8601).","maxLength":200,"title":"To Time","type":"string"},"name":{"description":"Metric name, for example 'transaction_duration' (list_metric_names returns the names of your app).","maxLength":200,"title":"Name","type":"string"},"field":{"description":"Which measurement to read from the metric.","enum":["GAUGE","COUNTER","MEAN","COUNT","MIN","MAX","P99","P95","P90","P80","P75","P70","P60","P50","P40","P30","P20","P10"],"title":"Field","type":"string"},"resolution":{"anyOf":[{"enum":["MINUTELY","HOURLY","DAILY"],"type":"string"},{"type":"null"}],"default":null,"description":"Interval between data points. MINUTELY only works for ranges of up to 12 hours that start within the last 48 hours.","title":"Resolution"},"aggregation":{"anyOf":[{"enum":["SUM","AVERAGE","MIN","MAX","FIRST","LAST"],"type":"string"},{"type":"null"}],"default":"AVERAGE","description":"How to combine several values inside one time bucket.","title":"Aggregation"},"namespace":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only data of this namespace, for example 'web' or 'background'; leave empty for all.","title":"Namespace"}},"required":["site_id","from_time","to_time","name","field"],"title":"query_metric_timeseriesArguments","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/query_metric_by_namespace":{"post":{"operationId":"query_metric_by_namespace","summary":"Get one aggregated metric value per namespace (web, background and others) over a time range, for example mean request d","description":"Get one aggregated metric value per namespace (web, background and others) over a time range, for example mean request duration per namespace. Use for \"Compare mean request duration per namespace in my AppSignal app last week\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"site_id":{"description":"Id of the AppSignal app (site), the id in the app's URL.","maxLength":200,"title":"Site Id","type":"string"},"from_time":{"description":"Start of the time range (ISO 8601, for example 2026-10-10T00:00:00Z).","maxLength":200,"title":"From Time","type":"string"},"to_time":{"description":"End of the time range (ISO 8601).","maxLength":200,"title":"To Time","type":"string"},"name":{"description":"Metric name, for example 'transaction_duration' (list_metric_names returns the names of your app).","maxLength":200,"title":"Name","type":"string"},"field":{"description":"Which measurement to read from the metric.","enum":["GAUGE","COUNTER","MEAN","COUNT","MIN","MAX","P99","P95","P90","P80","P75","P70","P60","P50","P40","P30","P20","P10"],"title":"Field","type":"string"},"resolution":{"anyOf":[{"enum":["MINUTELY","HOURLY","DAILY"],"type":"string"},{"type":"null"}],"default":null,"description":"Interval between data points. MINUTELY only works for ranges of up to 12 hours that start within the last 48 hours.","title":"Resolution"},"aggregation":{"anyOf":[{"enum":["SUM","AVERAGE","MIN","MAX","FIRST","LAST"],"type":"string"},{"type":"null"}],"default":"AVERAGE","description":"How to combine several values inside one time bucket.","title":"Aggregation"}},"required":["site_id","from_time","to_time","name","field"],"title":"query_metric_by_namespaceArguments","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_deploy_statistics":{"post":{"operationId":"get_deploy_statistics","summary":"Get request throughput, mean response time and error rate for one deploy (git revision), optionally for one namespace. U","description":"Get request throughput, mean response time and error rate for one deploy (git revision), optionally for one namespace. Use for \"How did revision abc123 perform in AppSignal\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"site_id":{"description":"Id of the AppSignal app (site), the id in the app's URL.","maxLength":200,"title":"Site Id","type":"string"},"revision":{"description":"Git revision or deploy identifier.","maxLength":200,"title":"Revision","type":"string"},"namespace":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only this namespace, for example 'web' or 'api'.","title":"Namespace"}},"required":["site_id","revision"],"title":"get_deploy_statisticsArguments","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}}}}