Error Tracking
Capture errors and exceptions, group them into issues, search and resolve — Sentry-style error monitoring.
1. Overview
https://api.infrai.cc/v1/errorsAuthorization: Bearer $INFRAI_API_KEY# Call any /v1/errors capability over raw HTTP — no SDK to install.
# curl:
curl https://api.infrai.cc/v1/errors/... \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json"2. Methods (9)
2.1errors.capture
Capture an application error with optional tags.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
message | string | Required | Human-readable error message. |
code | string | Optional | Optional application error code. |
stack | string | Optional | Optional stack trace. |
tags | Record<string, string> | Optional | Key/value tags for grouping. |
Returns
{ ok, error_id }| Name | Type | Description |
|---|---|---|
event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
fingerprint | string | Hex sha256 used for grouping. |
error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
is_new_group | boolean | Whether this capture created a new error group |
dashboard_url | string | URL to view this resource in the dashboardformat: uri |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/errors/capture \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/errors/capture",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/capture",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/capture",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/errors/capture", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/capture"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/errors/capture");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/capture");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/capture")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/errors/capture")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.2errors.message
上报一条结构化错误或日志消息
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
text | string | Required | 消息正文≥ 1 chars |
level | "debug" | "info" | "warning" | "error" | "fatal" | Optional | 级别:debug/info/warning/error/fataldefault: "info" |
tags | Record<string, string> | Optional | 键值标签,便于过滤与分组 |
user_id | string | Optional | 关联的用户 ID |
release | string | Optional | 发布版本标识 |
environment | "production" | "staging" | "development" | null | Optional | 环境:production/staging/development |
idempotency_key | string | Optional | 幂等键,用于避免重复写入 |
Returns
CaptureResult| Name | Type | Description |
|---|---|---|
event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
fingerprint | string | Hex sha256 used for grouping. |
error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
is_new_group | boolean | Whether this capture created a new error group |
dashboard_url | string | URL to view this resource in the dashboardformat: uri |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/errors/message \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "hello"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/errors/message",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'text': 'hello'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/message",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"text": "hello"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/message",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"text": "hello"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"text": "hello"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/errors/message", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/message"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"text\": \"hello\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/errors/message");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"text\": \"hello\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/message");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"text\": \"hello\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/message")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"text": "hello"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/errors/message")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"text": "hello"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.3errors.list
分页列出捕获到的错误事件
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
filter | Record<string, unknown> | Optional | 过滤条件(观测过滤 DSL) |
cursor | string | Optional | 分页游标 |
limit | number | Optional | 每页返回数量 |
Returns
ErrorEventList| Name | Type | Description |
|---|---|---|
items | object[] | Array of result items in this page |
items[].event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
items[].fingerprint | string | Hex sha256 grouping fingerprint. |
items[].error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
items[].timestamp | string | Unix timestamp of the data pointformat: date-time |
items[].level | "debug" | "info" | "warning" | "error" | "fatal" | Severity or log level (e.g. info, warn, error) |
items[].title | string | Short title or summary |
items[].message | string | null | Detailed message content |
items[].environment | string | null | Deployment environment (e.g. production, staging) |
items[].release | string | null | Software release version |
items[].user_id | string | null | User identifier associated with this resource |
items[].tags | object | null | Tags for categorization and filtering |
items[].is_resolved | boolean | Whether this error or group is marked as resolved |
items[].is_ignored | boolean | Whether this error or group is marked as ignored |
items[].dashboard_url | string | URL to view this resource in the dashboardformat: uri |
next_cursor | string | null | Opaque cursor to fetch the next page; null/absent if this is the last page |
total | integer | Total number of items across all pages≥ 0 |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/errors/list \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/errors/list", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/list"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/errors/list");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/list");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/list")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/errors/list")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.4errors.search
按关键词搜索错误事件
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
q | string | Required | 搜索关键词 |
filter | Record<string, unknown> | Optional | 过滤条件(观测过滤 DSL) |
cursor | string | Optional | 分页游标 |
limit | number | Optional | 每页返回数量 |
Returns
ErrorEventList| Name | Type | Description |
|---|---|---|
items | object[] | Array of result items in this page |
items[].event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
items[].fingerprint | string | Hex sha256 grouping fingerprint. |
items[].error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
items[].timestamp | string | Unix timestamp of the data pointformat: date-time |
items[].level | "debug" | "info" | "warning" | "error" | "fatal" | Severity or log level (e.g. info, warn, error) |
items[].title | string | Short title or summary |
items[].message | string | null | Detailed message content |
items[].environment | string | null | Deployment environment (e.g. production, staging) |
items[].release | string | null | Software release version |
items[].user_id | string | null | User identifier associated with this resource |
items[].tags | object | null | Tags for categorization and filtering |
items[].is_resolved | boolean | Whether this error or group is marked as resolved |
items[].is_ignored | boolean | Whether this error or group is marked as ignored |
items[].dashboard_url | string | URL to view this resource in the dashboardformat: uri |
next_cursor | string | null | Opaque cursor to fetch the next page; null/absent if this is the last page |
total | integer | Total number of items across all pages≥ 0 |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/errors/search \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/search",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/search",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/search",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/errors/search", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/search"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/errors/search");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/search");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/search")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/errors/search")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.5errors.get
按事件 ID 获取错误事件详情
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
event_id | string | Required | 错误事件 ID |
Returns
ErrorEvent| Name | Type | Description |
|---|---|---|
event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
fingerprint | string | Fingerprint hash for error groupingpattern: ^[a-f0-9]{64}$ |
error_group_id | string | Identifier of the error group this event belongs to |
timestamp | string | Unix timestamp of the data pointformat: date-time |
level | "debug" | "info" | "warning" | "error" | "fatal" | Severity or log level (e.g. info, warn, error) |
title | string | Short title or summary |
message | string | null | Detailed message content |
environment | "production" | "staging" | "development" | null | Deployment environment (e.g. production, staging) |
release | string | null | Software release version |
user_id | string | null | User identifier associated with this resource |
tags | object | Tags for categorization and filtering |
is_resolved | boolean | Whether this error or group is marked as resolveddefault: false |
is_ignored | boolean | Whether this error or group is marked as ignoreddefault: false |
exception | object | null | Exception details including type and stacktrace |
breadcrumbs | object[] | List of breadcrumb events leading up to the error |
context | object | Additional context data for the error |
extra | object | Extra metadata attached to the error event |
idempotency_key | string | null | Dedup key for errors.capture (route is idempotent:true). |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/errors/get/EVENT_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/get/EVENT_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/get/EVENT_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/get/EVENT_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/errors/get/EVENT_ID", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/get/EVENT_ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/errors/get/EVENT_ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/get/EVENT_ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/get/EVENT_ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/errors/get/EVENT_ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.6errors.groups
分页列出错误分组
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
status | 'unresolved' | 'resolved' | 'ignored' | Optional | 按状态过滤:unresolved/resolved/ignored |
sort | 'count_desc' | 'last_seen_desc' | 'first_seen_desc' | Optional | 排序方式:count_desc/last_seen_desc/first_seen_desc |
cursor | string | Optional | 分页游标 |
limit | number | Optional | 每页返回数量 |
Returns
ErrorGroupList| Name | Type | Description |
|---|---|---|
groups | object[] | List of error group objects |
groups[].error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
groups[].fingerprint | string | Fingerprint hash for error grouping |
groups[].title | string | Short title or summary |
groups[].first_seen_at | string | ISO 8601 timestamp when this was first observedformat: date-time |
groups[].last_seen_at | string | ISO 8601 timestamp when this was last observedformat: date-time |
groups[].count | integer | Total number of items across all pages≥ 1 |
groups[].user_count | integer | Number of unique users affected≥ 0 |
groups[].level | "debug" | "info" | "warning" | "error" | "fatal" | Severity or log level (e.g. info, warn, error) |
groups[].is_resolved | boolean | Whether this error or group is marked as resolved |
groups[].is_ignored | boolean | Whether this error or group is marked as ignored |
groups[].assigned_to | string | null | User assigned to investigate this error group |
groups[].sample_event_id | string | ID of a sample event from this error grouppattern: ^evt_err_[A-Za-z0-9]{20,}$ |
groups[].environments | string[] | null | List of environments where this error has been seen |
groups[].releases | string[] | null | List of software releases where this error has been seen |
groups[].trend_24h | object | null | Object with current, previous, and change_pct. |
groups[].sparkline | integer[] | null | 24-bucket hourly event counts for mini chart. |
groups[].dashboard_url | string | URL to view this resource in the dashboardformat: uri |
next_cursor | string | null | Opaque cursor for next page; null = end. |
total | integer | Total number of items across all pages≥ 0 |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/errors/groups \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/groups",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/groups",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/groups",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/errors/groups", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/groups"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/errors/groups");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/groups");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/groups")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/errors/groups")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.7errors.group_detail
获取错误分组的聚合详情
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
error_group_id | string | Required | 错误分组 ID |
Returns
ErrorGroupDetail| Name | Type | Description |
|---|---|---|
error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
fingerprint | string | Fingerprint hash for error grouping |
title | string | Short title or summary |
first_seen_at | string | ISO 8601 timestamp when this was first observedformat: date-time |
last_seen_at | string | ISO 8601 timestamp when this was last observedformat: date-time |
count | integer | Total number of items across all pages≥ 1 |
user_count | integer | Number of unique users affected≥ 0 |
level | string | Severity or log level (e.g. info, warn, error) |
is_resolved | boolean | Whether this error or group is marked as resolved |
is_ignored | boolean | Whether this error or group is marked as ignored |
assigned_to | string | null | User assigned to investigate this error group |
sample_event_id | string | ID of a sample event from this error group |
environments | string[] | null | List of environments where this error has been seen |
releases | string[] | null | List of software releases where this error has been seen |
trend_24h | object | null | 24-hour trend data for this error group |
sparkline | integer[] | null | Sparkline data points for error frequency visualization |
dashboard_url | string | URL to view this resource in the dashboardformat: uri |
representative_event | object | Representative error event for this group |
representative_event.event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
representative_event.fingerprint | string | Fingerprint hash for error grouping |
representative_event.error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
representative_event.timestamp | string | Unix timestamp of the data pointformat: date-time |
representative_event.level | "debug" | "info" | "warning" | "error" | "fatal" | Severity or log level (e.g. info, warn, error) |
representative_event.title | string | Short title or summary |
representative_event.message | string | null | Detailed message content |
representative_event.environment | string | null | Deployment environment (e.g. production, staging) |
representative_event.release | string | null | Software release version |
representative_event.user_id | string | null | User identifier associated with this resource |
representative_event.tags | object | null | Tags for categorization and filtering |
representative_event.is_resolved | boolean | Whether this error or group is marked as resolved |
representative_event.is_ignored | boolean | Whether this error or group is marked as ignored |
representative_event.dashboard_url | string | URL to view this resource in the dashboardformat: uri |
representative_event.exception | object | Exception details including type and stacktrace |
representative_event.exception.type | string | Exception class name, e.g. 'NullPointerException'. |
representative_event.exception.value | string | Exception message. |
representative_event.exception.stacktrace | object[] | Stack trace of the error |
representative_event.exception.stacktrace[].func | string | Function name in the stack frame |
representative_event.exception.stacktrace[].file | string | Source file name in the stack frame |
representative_event.exception.stacktrace[].line | integer | Line number in the source file≥ 0 |
representative_event.exception.stacktrace[].col | integer | null | Column number in the source file≥ 0 |
representative_event.exception.stacktrace[].in_app | boolean | true if frame is in user code; false for SDK / stdlib. |
representative_event.exception.stacktrace[].context_pre | string[] | null | Up to 5 lines of source before the error line. |
representative_event.exception.stacktrace[].context_line | string | null | Source line where the error occurred. |
representative_event.exception.stacktrace[].context_post | string[] | null | Source code lines after the error line |
representative_event.exception.stacktrace[].vars | object | null | Local variable snapshot (PII scrubbed). |
representative_event.breadcrumbs | object[] | List of breadcrumb events leading up to the error |
representative_event.breadcrumbs[].at | string | ISO 8601 timestamp of the eventformat: date-time |
representative_event.breadcrumbs[].category | string | Consent category (e.g. marketing, analytics)e.g. http |
representative_event.breadcrumbs[].message | string | Detailed message content |
representative_event.breadcrumbs[].level | "debug" | "info" | "warning" | "error" | "critical" | null | Severity or log level (e.g. info, warn, error) |
representative_event.breadcrumbs[].data | object | null | Free-form structured data attached to this breadcrumb. |
representative_event.context | object | null | Additional context data for the error |
representative_event.extra | object | null | Extra metadata attached to the error event |
representative_event.sdk | object | null | Object with name and version. |
representative_event.runtime | object | null | Object with name, version, and os. |
representative_event.request | object | null | HTTP request info (scrubbed). |
representative_event.user | object | null | User info (scrubbed). |
representative_event.fingerprint_source | "default" | "user" | "rule" | Source of the error fingerprint |
representative_event.received_at | string | ISO 8601 timestamp when the error was received by the serverformat: date-time |
representative_event.group_first_seen_at | string | ISO 8601 timestamp when this group was first seenformat: date-time |
representative_event.group_last_seen_at | string | ISO 8601 timestamp when this group was last seenformat: date-time |
representative_event.group_count | integer | Number of events in this error group≥ 1 |
representative_event.group_user_count | integer | Number of unique users affected in this group≥ 0 |
tag_distribution | object | null | Object mapping tag name to count. |
user_distribution | object | null | Top affected users: object mapping user_id to count. |
release_distribution | object | null | Distribution of events across software releases |
environment_distribution | object | null | Distribution of events across environments |
timeline | object[] | null | 24h time-series points. |
comments | object[] | null | List of comments on this error group |
activity_log | object[] | null | List of activity log entries for the error group |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.8errors.events
列出某错误分组下的事件
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
error_group_id | string | Required | 错误分组 ID |
cursor | string | Optional | 分页游标 |
limit | number | Optional | 每页返回数量 |
Returns
ErrorEventList| Name | Type | Description |
|---|---|---|
items | object[] | Array of result items in this page |
items[].event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
items[].fingerprint | string | Hex sha256 grouping fingerprint. |
items[].error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
items[].timestamp | string | Unix timestamp of the data pointformat: date-time |
items[].level | "debug" | "info" | "warning" | "error" | "fatal" | Severity or log level (e.g. info, warn, error) |
items[].title | string | Short title or summary |
items[].message | string | null | Detailed message content |
items[].environment | string | null | Deployment environment (e.g. production, staging) |
items[].release | string | null | Software release version |
items[].user_id | string | null | User identifier associated with this resource |
items[].tags | object | null | Tags for categorization and filtering |
items[].is_resolved | boolean | Whether this error or group is marked as resolved |
items[].is_ignored | boolean | Whether this error or group is marked as ignored |
items[].dashboard_url | string | URL to view this resource in the dashboardformat: uri |
next_cursor | string | null | Opaque cursor to fetch the next page; null/absent if this is the last page |
total | integer | Total number of items across all pages≥ 0 |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.9errors.resolve
将错误分组标记为已解决
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
error_group_id | string | Required | 错误分组 IDpattern: ^errgrp_[A-Za-z0-9]{20,}$ |
Returns
ErrorGroup| Name | Type | Description |
|---|---|---|
error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
fingerprint | string | Fingerprint hash for error grouping |
title | string | Short title or summary |
first_seen_at | string | ISO 8601 timestamp when this was first observedformat: date-time |
last_seen_at | string | ISO 8601 timestamp when this was last observedformat: date-time |
count | integer | Total number of items across all pages≥ 1 |
user_count | integer | Number of unique users affected≥ 0 |
level | string | Severity or log level (e.g. info, warn, error) |
is_resolved | boolean | Whether this error or group is marked as resolved |
is_ignored | boolean | Whether this error or group is marked as ignored |
assigned_to | string | null | User assigned to investigate this error group |
sample_event_id | string | ID of a sample event from this error group |
environments | string[] | null | List of environments where this error has been seen |
releases | string[] | null | List of software releases where this error has been seen |
trend_24h | object | null | 24-hour trend data for this error group |
sparkline | integer[] | null | Sparkline data points for error frequency visualization |
dashboard_url | string | URL to view this resource in the dashboardformat: uri |
representative_event | object | Representative error event for this group |
representative_event.event_id | string | Unique identifier for this eventpattern: ^evt_err_[A-Za-z0-9]{20,}$ |
representative_event.fingerprint | string | Fingerprint hash for error grouping |
representative_event.error_group_id | string | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
representative_event.timestamp | string | Unix timestamp of the data pointformat: date-time |
representative_event.level | "debug" | "info" | "warning" | "error" | "fatal" | Severity or log level (e.g. info, warn, error) |
representative_event.title | string | Short title or summary |
representative_event.message | string | null | Detailed message content |
representative_event.environment | string | null | Deployment environment (e.g. production, staging) |
representative_event.release | string | null | Software release version |
representative_event.user_id | string | null | User identifier associated with this resource |
representative_event.tags | object | null | Tags for categorization and filtering |
representative_event.is_resolved | boolean | Whether this error or group is marked as resolved |
representative_event.is_ignored | boolean | Whether this error or group is marked as ignored |
representative_event.dashboard_url | string | URL to view this resource in the dashboardformat: uri |
representative_event.exception | object | Exception details including type and stacktrace |
representative_event.exception.type | string | Exception class name, e.g. 'NullPointerException'. |
representative_event.exception.value | string | Exception message. |
representative_event.exception.stacktrace | object[] | Stack trace of the error |
representative_event.exception.stacktrace[].func | string | Function name in the stack frame |
representative_event.exception.stacktrace[].file | string | Source file name in the stack frame |
representative_event.exception.stacktrace[].line | integer | Line number in the source file≥ 0 |
representative_event.exception.stacktrace[].col | integer | null | Column number in the source file≥ 0 |
representative_event.exception.stacktrace[].in_app | boolean | true if frame is in user code; false for SDK / stdlib. |
representative_event.exception.stacktrace[].context_pre | string[] | null | Up to 5 lines of source before the error line. |
representative_event.exception.stacktrace[].context_line | string | null | Source line where the error occurred. |
representative_event.exception.stacktrace[].context_post | string[] | null | Source code lines after the error line |
representative_event.exception.stacktrace[].vars | object | null | Local variable snapshot (PII scrubbed). |
representative_event.breadcrumbs | object[] | List of breadcrumb events leading up to the error |
representative_event.breadcrumbs[].at | string | ISO 8601 timestamp of the eventformat: date-time |
representative_event.breadcrumbs[].category | string | Consent category (e.g. marketing, analytics)e.g. http |
representative_event.breadcrumbs[].message | string | Detailed message content |
representative_event.breadcrumbs[].level | "debug" | "info" | "warning" | "error" | "critical" | null | Severity or log level (e.g. info, warn, error) |
representative_event.breadcrumbs[].data | object | null | Free-form structured data attached to this breadcrumb. |
representative_event.context | object | null | Additional context data for the error |
representative_event.extra | object | null | Extra metadata attached to the error event |
representative_event.sdk | object | null | Object with name and version. |
representative_event.runtime | object | null | Object with name, version, and os. |
representative_event.request | object | null | HTTP request info (scrubbed). |
representative_event.user | object | null | User info (scrubbed). |
representative_event.fingerprint_source | "default" | "user" | "rule" | Source of the error fingerprint |
representative_event.received_at | string | ISO 8601 timestamp when the error was received by the serverformat: date-time |
representative_event.group_first_seen_at | string | ISO 8601 timestamp when this group was first seenformat: date-time |
representative_event.group_last_seen_at | string | ISO 8601 timestamp when this group was last seenformat: date-time |
representative_event.group_count | integer | Number of events in this error group≥ 1 |
representative_event.group_user_count | integer | Number of unique users affected in this group≥ 0 |
tag_distribution | object | null | Object mapping tag name to count. |
user_distribution | object | null | Top affected users: object mapping user_id to count. |
release_distribution | object | null | Distribution of events across software releases |
environment_distribution | object | null | Distribution of events across environments |
timeline | object[] | null | 24h time-series points. |
comments | object[] | null | List of comments on this error group |
activity_log | object[] | null | List of activity log entries for the error group |
Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"error_group_id": "sample"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'error_group_id': 'sample'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"error_group_id": "sample"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"error_group_id": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"error_group_id": "sample"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"error_group_id\": \"sample\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"error_group_id\": \"sample\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"error_group_id\": \"sample\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"error_group_id": "sample"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/errors/resolve/ERROR_GROUP_ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"error_group_id": "sample"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}3. All capabilities
Every routed capability in this module — the complete public REST contract. The methods above are the guided walkthrough; this index is the full reference.
errors.capturePOST /v1/errors/captureCapture an error event, aggregated into a group by fingerprint.
Parameters (13)
| Name | Type | Required | Description |
|---|---|---|---|
title | string | null | Optional | Short error title; falls back to message or exception.value. |
message | string | null | Optional | Detailed message content |
exception | object | null | Optional | Structured exception, e.g. {type, value, stacktrace}. |
level | string | Optional | Severity level (e.g. error, warning, info).default: "error" |
tags | object | null | Optional | Tags for categorization and filtering |
user_id | string | null | Optional | User identifier associated with this resource |
fingerprint | string | string[] | null | Optional | Grouping fingerprint. |
breadcrumbs | object[] | null | Optional | List of breadcrumb events leading up to the error |
context | object | null | Optional | Additional context data for the error |
extra | object | null | Optional | Extra metadata attached to the error event |
environment | string | null | Optional | Deployment environment (e.g. production, staging) |
release | string | null | Optional | Software release version |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
errors.eventsGET /v1/errors/events/{error_group_id}Page through all events within an error group.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
error_group_id | string | Required | Path parameter. |
errors.getGET /v1/errors/get/{event_id}Get the details of one error event by event ID.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
event_id | string | Required | Path parameter. |
errors.group_detailGET /v1/errors/group_detail/{error_group_id}Get the aggregated details of a specified error group.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
error_group_id | string | Required | Path parameter. |
errors.groupsGET /v1/errors/groupsPage through error groups, with status filtering and sorting.
No request parameters.
errors.listGET /v1/errors/listPage through captured error events, with filtering.
No request parameters.
errors.messagePOST /v1/errors/messageCapture a structured error/log message (level, tags, user, release, environment).
Parameters (7)
| Name | Type | Required | Description |
|---|---|---|---|
text | string | Required | Message body; becomes the event title.≥ 1 chars |
level | "debug" | "info" | "warning" | "error" | "fatal" | Optional | Severity or log level (e.g. info, warn, error)default: "info" |
tags | object | null | Optional | Tags for categorization and filtering |
user_id | string | null | Optional | User identifier associated with this resource |
release | string | null | Optional | Software release version |
environment | "production" | "staging" | "development" | null | Optional | Deployment environment (e.g. production, staging) |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
errors.resolvePOST /v1/errors/resolve/{error_group_id}Mark an error group as resolved.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
error_group_id | string | Required | Identifier of the error group this event belongs topattern: ^errgrp_[A-Za-z0-9]{20,}$ |
errors.searchGET /v1/errors/searchFull-text search error events by keyword.
No request parameters.
4. End-to-end example
A production-style walkthrough of this module: configure once, then run the flow. It exercises most of the module's APIs.
A copy-paste-runnable single-file Python program (stdlib only, no SDK): set your INFRAI_API_KEY, run it, and walk this module's core flow with REAL billed calls — later steps reuse real fields returned by earlier ones. The 12-line helper is the entire integration.
#!/usr/bin/env python3
"""Infrai · errors — runnable real-app example (single file, zero deps).
Copy this file, set your key, run it: every step is a REAL call to
api.infrai.cc, billed at the real (tiny) per-call price, printing the
live JSON response. Get a key at https://infrai.cc/login (Google/
GitHub sign-in grants $2 free credit); add funds at
https://infrai.cc/billing. No SDK — the 12-line helper below is the
entire integration."""
import json
import os
from urllib import error, request
KEY = os.environ.get("INFRAI_API_KEY") or "ifr_..." # <- your key
BASE = "https://api.infrai.cc"
# Same raw HTTPS POST/GET as every per-method example on this page —
# wrapped once for reuse. There is nothing else to it: no SDK.
def infrai(method, path, body=None):
req = request.Request(
BASE + path, method=method,
data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": f"Bearer {KEY}",
"Content-Type": "application/json"})
try:
with request.urlopen(req, timeout=60) as r:
return json.loads(r.read())
except error.HTTPError as e:
return json.loads(e.read())
def show(label, resp):
print(f"\n== {label} ==")
print(json.dumps(resp, indent=2, ensure_ascii=False))
return resp
# 1) errors.capture — POST /v1/errors/capture · Capture an error event, aggregated into a group by fingerprint.
r1 = show("errors.capture", infrai("POST", "/v1/errors/capture", {"exception":{"type":"ValueError","message":"bad input","stacktrace":"..."},"level":"error"}))
# 2) errors.message — POST /v1/errors/message · Capture a structured error/log message (level, tags, user, release, environment).
r2 = show("errors.message", infrai("POST", "/v1/errors/message", {"text":"hello"}))
# 3) errors.list — GET /v1/errors/list · Page through captured error events, with filtering.
r3 = show("errors.list", infrai("GET", "/v1/errors/list"))
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."# 1) Auth: every call is a raw HTTPS request to the Infrai gateway carrying
# only your project key. No SDK, no install.
# Get your key: sign in with Google/GitHub at https://infrai.cc/login for a
# project key + $2 free credit (email sign-in starts at $0). On 402
# INSUFFICIENT_CREDIT, add funds at https://infrai.cc/billing (or POST
# /v1/account/topup and open the returned checkout_url).
export INFRAI_API_KEY="ifr_..." # from https://infrai.cc/login
# 2) errors.capture
curl -X POST https://api.infrai.cc/v1/errors/capture \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"exception": {"type": "ValueError", "message": "bad input", "stacktrace": "..."}, "level": "error"}'
# 3) errors.message
curl -X POST https://api.infrai.cc/v1/errors/message \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "hello"}'
# 4) errors.list
curl -X GET https://api.infrai.cc/v1/errors/list \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 5) errors.search
curl -X GET https://api.infrai.cc/v1/errors/search \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 6) errors.get
curl -X GET https://api.infrai.cc/v1/errors/get/EVENT_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 7) errors.groups
curl -X GET https://api.infrai.cc/v1/errors/groups \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 8) errors.group_detail
curl -X GET https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 9) errors.events
curl -X GET https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 1) Auth: every call is a raw HTTPS request carrying only your project key.
# No SDK to install — just the `requests` library.
import os, requests
BASE = "https://api.infrai.cc"
HEADERS = {
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
"Content-Type": "application/json",
}
# 2) errors.capture
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/errors/capture",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'exception': {'type': 'ValueError', 'message': 'bad input', 'stacktrace': '...'}, 'level': 'error'},
)
resp.raise_for_status()
print(resp.json())
# 3) errors.message
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/errors/message",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'text': 'hello'},
)
resp.raise_for_status()
print(resp.json())
# 4) errors.list
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 5) errors.search
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/search",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 6) errors.get
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/get/EVENT_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 7) errors.groups
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/groups",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 8) errors.group_detail
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 9) errors.events
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
// 1) Auth: every call is a raw HTTPS request carrying only your project key.
// No SDK to install — just the built-in fetch().
const BASE = "https://api.infrai.cc";
const HEADERS = {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
};
// 2) errors.capture
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/capture",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"exception": {"type": "ValueError", "message": "bad input", "stacktrace": "..."}, "level": "error"}),
},
);
console.log(await resp.json());
// 3) errors.message
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/message",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"text": "hello"}),
},
);
console.log(await resp.json());
// 4) errors.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 5) errors.search
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/search",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 6) errors.get
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/get/EVENT_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 7) errors.groups
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/groups",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 8) errors.group_detail
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 9) errors.events
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 1) Auth: every call is a raw HTTPS request carrying only your project key.
// No SDK to install — just the built-in fetch(), typed.
const BASE = "https://api.infrai.cc";
const HEADERS: Record<string, string> = {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
};
// 2) errors.capture
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/capture",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"exception": {"type": "ValueError", "message": "bad input", "stacktrace": "..."}, "level": "error"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 3) errors.message
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/message",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"text": "hello"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 4) errors.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 5) errors.search
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/search",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 6) errors.get
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/get/EVENT_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 7) errors.groups
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/groups",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 8) errors.group_detail
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/group_detail/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 9) errors.events
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/errors/events/ERROR_GROUP_ID",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);