> ## Documentation Index
> Fetch the complete documentation index at: https://help.decodo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Go SDK

> 面向 Decodo API 的官方 Go SDK，提供类型化、面向特定目标的请求参数，以及同步、异步和批量抓取方法。

> [!NOTE]
>
> 最新的安装说明、示例和源代码请查看 [Go SDK GitHub 仓库](https://github.com/Decodo/sdk-go)。

使用官方 Decodo Go SDK，为搜索引擎、电商平台、社交媒体、AI 工具等构建类型化的抓取工作流。

* 类型化、面向特定目标的请求参数，支持编辑器自动补全
* 同步、异步和批量抓取方法
* 通过 Web Data API 提供网页搜索、站点地图和爬取功能
* 依据当前 Decodo 目标 schema 进行运行时校验
* 类型化的错误集合，让集成更安全
* 标准库之外仅有一个依赖；需要 Go 1.21 或更高版本

## 什么是 Decodo Go SDK？

Decodo Go SDK 为 Google、Amazon、TikTok、YouTube、ChatGPT、Perplexity 等 Decodo 目标提供类型化接口。您无需手动拼装 HTTP 请求和校验载荷，而是直接在编辑器中使用类型化构造函数和特定目标的参数结构体。

## 为什么使用该 SDK？

* **类型化与自动补全**：每个目标都有自己的参数结构体，编辑器因此知道它接受哪些字段。
* **统一的抓取接口**：通过同一个 SDK 使用搜索引擎、电商平台、社交媒体和 AI 工具。
* **异步与批量工作流**：创建抓取任务、轮询任务状态，并大规模处理批量请求。
* **类型化错误**：显式处理身份验证、参数校验、超时和速率限制等失败情况。
* **由 schema 生成**：目标常量和参数结构体均由 Decodo schema 生成，该 schema 同时用于运行时校验。
* **配置极简**：仅需一个用于 schema 校验的依赖，其余均使用标准库。

## 要求

* Go 1.21 或更高版本。运行 `go version` 可检查版本，或[安装 Go](https://go.dev/doc/install)。

## 安装

```bash theme={null}
go get github.com/decodo/sdk-go
```

## 快速开始

创建一个新项目：

```bash theme={null}
mkdir scraper
cd scraper
go mod init scraper
go get github.com/decodo/sdk-go
touch main.go
```

在 [**Decodo 控制面板**](https://dashboard.decodo.com/web-data/playground)中，从您的 Web Data API 订阅复制 Web Data API 密钥。请通过环境变量导出，避免写入源代码：

```bash theme={null}
export DECODO_API_KEY=your_api_key
```

> [!NOTE]
>
> 较旧的计划只有基本身份验证令牌。请设置 `Token` 而不是 `APIKey`——详见下文的"配置"一节。

每个目标都有一个返回其参数结构体的构造函数。创建您需要的那个，设置字段，然后传给 `Scrape`：

```go theme={null}
// main.go
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/decodo/sdk-go"
)

func main() {
	client := decodo.NewClient(decodo.Config{
		WebScrapingAPI: &decodo.WebScrapingAPIConfig{
			APIKey: os.Getenv("DECODO_API_KEY"),
		},
	})

	params := decodo.NewGoogleSearchParams()
	params.Query = decodo.Ptr("coffee shops")
	params.Geo = decodo.Ptr("United States")
	params.Parse = decodo.Ptr(true)

	result, err := client.WebScrapingAPI.Scrape(context.Background(), params)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result.Results[0].Content)
}
```

运行程序：

```bash theme={null}
go run main.go
```

每个构造函数都固定了自己的目标，并返回只包含该目标所支持字段的结构体，因此您永远不需要传入目标名称或拼装通用参数映射。

您的编辑器会标出拼写错误或不受支持的字段，SDK 也会在发送请求之前，依据目标 schema 校验具体取值。

## 设置可选参数

可选参数是指针字段，因此"未设置"可以与"零值"区分开。请使用 `decodo.Ptr` 在行内设置它们：

```go theme={null}
params.Query = decodo.Ptr("shoes")
params.Parse = decodo.Ptr(true)
params.PageFrom = decodo.Ptr(1)
```

## 配置

```go theme={null}
client := decodo.NewClient(decodo.Config{
	WebScrapingAPI: &decodo.WebScrapingAPIConfig{
		APIKey:            "<api_key>",
		IntegrationHeader: "my-app",
	},
	TimeoutMs: 120_000, // optional, request timeout in ms (default: 180000)
})
```

请设置 `APIKey` 或 `Token` 之一，切勿同时设置：

```go theme={null}
// Basic authentication token (older plans)
client := decodo.NewClient(decodo.Config{
	WebScrapingAPI: &decodo.WebScrapingAPIConfig{
		Token: "<basic_auth_token>",
	},
})
```

| 参数 | 说明 |
| - | - |
| `WebScrapingAPI.APIKey` | 控制面板中订阅所对应的 Web Data API 密钥。**推荐** |
| `WebScrapingAPI.Token` | 较旧计划的基本身份验证令牌——即 base64 编码的 `user:password` 字符串。请用它替代 `APIKey` |
| `WebScrapingAPI.IntegrationHeader` | 在请求中标识调用方集成（默认：`sdk-go`） |
| `TimeoutMs` | 请求超时毫秒数（默认：180000） |
| `Schema` | 用于请求校验的目标 schema（默认：自动加载） |

> [!NOTE]
>
> 同时设置两者会返回 `*decodo.ConfigurationError`：`WebScrapingAPI accepts either Token or APIKey, not both.` 凭据还决定了 SDK 调用哪个 API：`APIKey` 使用位于 `data.decodo.com` 的 Web Data API，这也是使用搜索、站点地图和爬取功能的唯一途径；`Token` 使用位于 `scraper-api.decodo.com` 的旧版 Web Scraping API，该 API 仅支持抓取。

## 抓取

通过 `client.WebScrapingAPI` 访问该 API。

| 方法 | 返回内容 |
| - | - |
| `Scrape(ctx, params)` | 请求完成后返回抓取结果。 |
| `ScrapeAsync(ctx, params)` | 立即返回一个抓取任务。 |
| `GetStatus(ctx, taskID)` | 任务的当前状态，以 `TaskStatus` 常量表示 |
| `GetResults(ctx, taskID)` | 任务的结果；若尚未就绪则返回 `nil` |
| `ScrapeBatch(ctx, params)` | 一个批量任务，每个输入对应一个 query |
| `Search(ctx, params)` | 解析后的网页搜索结果。需要 `APIKey` |
| `Map(ctx, params)` | 在站点上发现的链接。需要 `APIKey` |
| `Crawl(ctx, params, opts...)` | 爬取结束后的所有页面。需要 `APIKey` |
| `StartCrawl(ctx, params)` | 立即返回的爬取 ID。需要 `APIKey` |
| `GetCrawlStatus(ctx, crawlID)` | 爬取的进度和状态。需要 `APIKey` |
| `GetCrawlResults(ctx, crawlID, opts...)` | 爬取得到的页面。需要 `APIKey` |
| `CancelCrawl(ctx, crawlID)` | 停止正在运行的爬取。需要 `APIKey` |

### 同步抓取

等待抓取结果返回后再继续：

```go theme={null}
params := decodo.NewAmazonProductParams()
params.Query = decodo.Ptr("B09H74FXNW")
params.Parse = decodo.Ptr(true)

result, err := client.WebScrapingAPI.Scrape(context.Background(), params)
if err != nil {
	log.Fatal(err)
}
fmt.Println(result.Results[0].Content)
```

### 异步抓取

创建抓取任务并立即返回。之后您需要轮询其状态和结果：

```go theme={null}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()

params := decodo.NewGoogleSearchParams()
params.Query = decodo.Ptr("laptop reviews")
params.Parse = decodo.Ptr(true)

task, err := client.WebScrapingAPI.ScrapeAsync(ctx, params)
if err != nil {
	log.Fatal(err)
}

for {
	status, err := client.WebScrapingAPI.GetStatus(ctx, task.ID)
	if err != nil {
		log.Fatal(err)
	}
	if status.Status == decodo.TaskStatusDone {
		break
	}
	if status.Status == decodo.TaskStatusFaulted {
		log.Fatalf("Scraping task %s failed.", task.ID)
	}
	time.Sleep(2 * time.Second)
}

results, err := client.WebScrapingAPI.GetResults(ctx, task.ID)
if err != nil {
	log.Fatal(err)
}
fmt.Println(results.Results[0].Content)
```

`GetStatus` 会返回 `decodo.TaskStatusPending`、`decodo.TaskStatusDone` 或 `decodo.TaskStatusFaulted` 之一。在结果可用之前，`GetResults` 会返回 `nil`。

### 批量抓取

每个受支持的目标也都有批量构造函数，例如 `NewGoogleSearchBatchParams()`。在批量请求中，`URL` 或 `Query` 等字段接受切片，其中每个值都会成为一个独立任务：

```go theme={null}
params := decodo.NewGoogleSearchBatchParams()
params.Query = []string{"coffee", "tea", "juice"}
params.Parse = decodo.Ptr(true)

batch, err := client.WebScrapingAPI.ScrapeBatch(ctx, params)
if err != nil {
	log.Fatal(err)
}

for _, query := range batch.Queries {
	for {
		status, err := client.WebScrapingAPI.GetStatus(ctx, query.ID)
		if err != nil {
			log.Fatal(err)
		}
		if status.Status == decodo.TaskStatusDone {
			break
		}
		if status.Status == decodo.TaskStatusFaulted {
			log.Fatalf("Scraping task %s failed.", query.ID)
		}
		time.Sleep(2 * time.Second)
	}
	result, err := client.WebScrapingAPI.GetResults(ctx, query.ID)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result.Results[0].Content)
}
```

> [!NOTE]
>
> 一个批量请求只针对单个目标，该目标由构造函数为您固定。`URL` 和 `Query` 是仅有的两个接受多个值的字段；其余字段均使用各自的常规类型。
>
> `ScrapeBatch` 不支持 `walmart_product`、`target_product`、`tiktok_shop_product`、`chatgpt`、`gemini` 和 `perplexity`。这些目标请改用 `ScrapeAsync`。批量请求限制为每秒一次，并且会跳过 schema 校验，因为该 schema 描述的是单个值。

## Web Data API：搜索、站点地图和爬取

这些方法由位于 `data.decodo.com` 的 Web Data API 提供，**需要 `APIKey`**。在配置了基本身份验证 `Token` 的客户端上调用它们，会在发出任何请求之前返回 `*decodo.ConfigurationError`，例如：`Search requires an API key. Configure WebScrapingAPIConfig.APIKey instead of Token.` 请使用 `errors.As` 进行匹配。

### 搜索

```go theme={null}
serp, err := client.WebScrapingAPI.Search(ctx, decodo.RunSearchRequest{
	Query: "laptop reviews",
	Geo:   decodo.Ptr("United States"),
})
```

### 站点地图

```go theme={null}
site, err := client.WebScrapingAPI.Map(ctx, decodo.MapSiteRequest{
	URL:   "https://example.com",
	Limit: decodo.Ptr(100),
})
```

### 爬取

`Crawl` 会启动爬取、持续轮询直到结束，并返回所有页面：

```go theme={null}
pages, err := client.WebScrapingAPI.Crawl(ctx,
	decodo.StartCrawlRequest{URL: "https://example.com", Limit: decodo.Ptr(50)},
	decodo.WithPollInterval(5*time.Second),
)
```

若要自行控制爬取流程，请先启动爬取，再分别轮询：

```go theme={null}
job, err := client.WebScrapingAPI.StartCrawl(ctx, decodo.StartCrawlRequest{URL: "https://example.com"})

status, err := client.WebScrapingAPI.GetCrawlStatus(ctx, job.CrawlID)

pages, err := client.WebScrapingAPI.GetCrawlResults(ctx, job.CrawlID, decodo.WithMetadataOnly())

_, err = client.WebScrapingAPI.CancelCrawl(ctx, job.CrawlID)
```

| 选项 | 效果 |
| - | - |
| `decodo.WithPollInterval(d)` | `Crawl` 检查状态的频率（默认：5 秒） |
| `decodo.WithMetadataOnly()` | 只返回页面元数据，不返回页面内容 |

> [!NOTE]
>
> `GetCrawlResults` 会在内部自行处理 API 的分页并返回所有页面，因此不存在单独的列出页面的调用。TypeScript SDK 的 `listCrawlPages` 在 Go 中没有对应方法。
>
> `Crawl` 会包装其失败信息，因此请使用 `errors.As` 而不是类型分支来匹配——详见下文的"错误处理"一节。

## 目标与参数构造函数

每个目标都有与之对应的构造函数。目标名称会转换为 PascalCase，加上 `New` 前缀和 `Params` 后缀——例如 `google_search` → `NewGoogleSearchParams()`。批量构造函数遵循同样的规则，例如 `NewGoogleSearchBatchParams()`。

您无需显式传入目标，因为每个构造函数都已固定了自己的目标。每个参数结构体也带有一个 `Target` 字段，`GetTarget()` 会以字符串形式返回它。

每个目标接受一个主输入字段（`URL`、`Query`、`ProductID` 或 `Prompt`），以及 `Parse`、`Markdown`、`Geo` 或 `CallbackURL` 等可选配置。可用的可选字段因目标而异，请借助编辑器自动补全或[参数文档](https://help.decodo.com/docs/web-scraping-api-parameters-overview.md)。

### 搜索引擎

| 目标 | 说明 | 主输入 | 构造函数 |
| - | - | - | - |
| `google_search` | 某个查询的 Google 搜索结果 | `Query` | `NewGoogleSearchParams()` |
| `google_lens` | Google Lens 以图搜图 | `Query` | `NewGoogleLensParams()` |
| `google_ads` | 某个查询的 Google Ads 结果 | `Query` | `NewGoogleAdsParams()` |
| `google_travel_hotels` | Google Travel 酒店列表 | `Query` | `NewGoogleTravelHotelsParams()` |
| `bing_search` | Bing 搜索结果 | `Query` | `NewBingSearchParams()` |

### 电商

| 目标 | 说明 | 主输入 | 构造函数 |
| - | - | - | - |
| `amazon_product` | 按 ASIN 获取 Amazon 商品详情页 | `Query` | `NewAmazonProductParams()` |
| `amazon_search` | Amazon 搜索结果 | `Query` | `NewAmazonSearchParams()` |
| `amazon_pricing` | Amazon 价格和报价 | `Query` | `NewAmazonPricingParams()` |
| `amazon_sellers` | Amazon 卖家列表 | `Query` | `NewAmazonSellersParams()` |
| `amazon_bestsellers` | 按类目获取 Amazon 畅销榜 | `Query` | `NewAmazonBestsellersParams()` |
| `walmart_product` | 按商品 ID 获取 Walmart 商品页面 | `ProductID` | `NewWalmartProductParams()` |
| `walmart_search` | Walmart 搜索结果 | `Query` | `NewWalmartSearchParams()` |
| `target_product` | 按商品 ID 获取 Target.com 商品页面 | `ProductID` | `NewTargetProductParams()` |
| `target_search` | Target.com 搜索结果 | `Query` | `NewTargetSearchParams()` |

### 社交媒体

| 目标 | 说明 | 主输入 | 构造函数 |
| - | - | - | - |
| `youtube_search` | YouTube 搜索结果 | `Query` | `NewYoutubeSearchParams()` |
| `youtube_metadata` | 按 ID 获取 YouTube 视频元数据 | `Query` | `NewYoutubeMetadataParams()` |
| `youtube_subtitles` | 按 ID 获取 YouTube 视频字幕 | `Query` | `NewYoutubeSubtitlesParams()` |
| `youtube_channel` | 按 handle 或 ID 获取 YouTube 频道 | `Query` | `NewYoutubeChannelParams()` |
| `tiktok_post` | 按 URL 获取 TikTok 帖子 | `URL` | `NewTiktokPostParams()` |
| `tiktok_shop_search` | TikTok Shop 搜索结果 | `Query` | `NewTiktokShopSearchParams()` |
| `tiktok_shop_product` | 按商品 ID 获取 TikTok Shop 商品页面 | `ProductID` | `NewTiktokShopProductParams()` |

### AI 工具

| 目标 | 说明 | 主输入 | 构造函数 |
| - | - | - | - |
| `chatgpt` | 针对某个提示词的 ChatGPT 回答 | `Prompt` | `NewChatgptParams()` |
| `perplexity` | 针对某个提示词的 Perplexity 回答 | `Prompt` | `NewPerplexityParams()` |
| `gemini` | 针对某个提示词的 Gemini 回答 | `Prompt` | `NewGeminiParams()` |
| `google_ai_mode` | Google AI 模式的回答 | `Query` | `NewGoogleAiModeParams()` |

### 其他

| 目标 | 说明 | 主输入 | 构造函数 |
| - | - | - | - |
| `airbnb` | 按 URL 获取 Airbnb 房源 | `URL` | `NewAirbnbParams()` |
| `apple_app_store` | 按 URL 获取 Apple App Store 应用 | `URL` | `NewAppleAppStoreParams()` |
| `autotrader` | 按 URL 获取 Autotrader 条目 | `URL` | `NewAutotraderParams()` |
| `bbb` | 按 URL 获取 Better Business Bureau 条目 | `URL` | `NewBbbParams()` |
| `mobile` | 按 URL 获取 Mobile.de 条目 | `URL` | `NewMobileParams()` |

### 通用目标与原始 URL 抓取

| 目标 | 说明 | 主输入 | 构造函数 |
| - | - | - | - |
| `universal` | 通过通用抓取器抓取任意 URL | `URL` | `NewUniversalParams()` |
| `google` | 原始 Google URL 抓取 | `URL` | `NewGoogleParams()` |
| `bing` | 原始 Bing URL 抓取 | `URL` | `NewBingParams()` |
| `amazon` | 原始 Amazon URL 抓取 | `URL` | `NewAmazonParams()` |
| `walmart` | 原始 Walmart URL 抓取 | `URL` | `NewWalmartParams()` |
| `target` | 原始 Target.com URL 抓取 | `URL` | `NewTargetParams()` |
| `tiktok` | 原始 TikTok URL 抓取 | `URL` | `NewTiktokParams()` |

> [!NOTE]
>
> Go SDK 提供 40 个目标。各 Decodo SDK 的覆盖范围并不相同，因此 TypeScript SDK 中可用的目标在这里未必可用——`ecommerce`、`universal_ecommerce`、`google_maps`、`google_suggest`、`google_shopping_search`、`youtube_video` 和 `youtube_transcript` 在 Go 中没有对应的构造函数。任意 URL 请使用 `universal`。

完整的目标列表和参数详情，请参阅[**目标列表**](https://help.decodo.com/docs/cn/web-scraping-api-targets.md)和[**参数**](https://help.decodo.com/docs/web-scraping-api-parameters-overview.md)。

## Schema 校验

Go 会在编译期检查字段是否存在以及类型是否正确。具体取值则在运行时另行依据 Decodo 目标 schema 进行校验。

未配置 `Schema` 时，客户端会使用 `decodo.SharedDefaultSchema`：它在首次使用时加载最新 schema，并在 `~/.decodo/decodo.ir.json` 缓存 24 小时。该加载每个进程只执行一次，因此获取失败不会重试：SDK 会记录一条警告，并在该会话中禁用校验后继续运行。

```go theme={null}
schema, err := decodo.LoadRemoteSchema(decodo.RemoteSchemaOptions{
	TTLMs:     3_600_000, // re-fetch after an hour instead of the default 24
	CachePath: "/tmp/decodo.ir.json", // optional, overrides ~/.decodo/decodo.ir.json
})
if err != nil {
	log.Fatal(err)
}

client := decodo.NewClient(decodo.Config{
	WebScrapingAPI: &decodo.WebScrapingAPIConfig{APIKey: os.Getenv("DECODO_API_KEY")},
	Schema:         schema,
})
```

## 错误处理

该 SDK 会返回与 API 错误码对应的类型化错误：

```go theme={null}
result, err := client.WebScrapingAPI.Scrape(ctx, params)
if err != nil {
	switch e := err.(type) {
	case *decodo.AuthenticationError:
		log.Fatalf("Invalid API key or token (HTTP %d). Check your credentials in the dashboard.", e.StatusCode)
	case *decodo.RateLimitError:
		time.Sleep(5 * time.Second)
		result, err = client.WebScrapingAPI.Scrape(ctx, params)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(result.Results[0].Content)
	case *decodo.ValidationError:
		fmt.Println("Payload rejected:", e.Errors)
	case *decodo.TimeoutError:
		fmt.Println("Timed out. Increase TimeoutMs or switch to ScrapeAsync for slow targets:", e.Msg)
	case *decodo.CancellationError:
		fmt.Println("Cancelled:", e.Msg)
	default:
		fmt.Printf("Request failed: %v\n", err)
	}
}
```

`AuthenticationError`、`RateLimitError` 和 `ValidationError` 都内嵌了 `DecodoError` 并实现了 `Unwrap`。因此，`errors.Is` 和 `errors.As` 对 `*decodo.DecodoError` 同样有效。

> [!WARNING]
>
> 类型分支只能匹配错误自身的类型。`Crawl` 会包装其失败信息，因此类型分支会把它们全部送入 `default`。对于任何可能来自爬取的错误，请使用 `errors.As`：
>
> ```go theme={null}
> pages, err := client.WebScrapingAPI.Crawl(ctx, req)
> if err != nil {
> 	var timeout *decodo.CrawlTimeoutError
> 	var crawlErr *decodo.CrawlError
> 	switch {
> 	case errors.As(err, &timeout):
> 		log.Printf("still running, collect it later: %s", timeout.CrawlID)
> 	case errors.As(err, &crawlErr):
> 		log.Printf("crawl %s ended %s: %s", crawlErr.CrawlID, crawlErr.Status, crawlErr.Reason)
> 	default:
> 		log.Fatal(err)
> 	}
> }
> ```

| 错误 | 返回时机 | 常用字段 |
| - | - | - |
| `AuthenticationError` | API 返回 `401` 或 `403` | `StatusCode`、`APIStatus`、`Message` |
| `RateLimitError` | API 返回 `429` | `StatusCode`、`APIStatus`、`Message` |
| `ValidationError` | API 返回 `422`，或返回带校验错误的 `400` | `Errors`，以及 `DecodoError` 的各字段 |
| `TimeoutError` | 请求超过 `TimeoutMs` | `Msg` |
| `CancellationError` | 调用方的 context 被取消 | `Msg` |
| `ConfigurationError` | 凭据缺失、两种凭据同时设置，或使用基本身份验证 `Token` 调用了 Web Data API 方法 | `Msg` |
| `CrawlError` | `Crawl` 以 `faulted` 或 `cancelled` 结束 | `CrawlID`、`Status`、`Reason` |
| `CrawlTimeoutError` | `Crawl` 超过其 context 截止时间。除非设置了 `Finished`，否则爬取仍会继续运行 | `CrawlID`、`Finished` |
| `CrawlRequestError` | 爬取启动后请求失败，例如轮询时出现 5xx。可解包为底层错误 | `CrawlID`、`Finished`、`Err` |
| `CrawlCancellationError` | `Crawl` 的 context 被取消。可解包为 `*CancellationError` | `CrawlID`、`Finished` |
| `DecodoError` | 其他任何失败响应——被上述三种 HTTP 错误内嵌 | `StatusCode`、`APIStatus`、`Message` |

> [!NOTE]
>
> `TimeoutError` 和 `CancellationError` 不在 `DecodoError` 的层级之内，且只携带 `Msg`，因此针对 `*decodo.DecodoError` 的判断无法匹配它们。
>
> 此外，当目标 schema 无法获取时，schema 校验也可能被跳过。在这种情况下，非法取值可能会到达 API，并以 API 错误的形式返回，而不是在编译期或本地校验阶段被发现。

***

## 相关内容

* **[CLI](https://help.decodo.com/docs/cn/cli.md)**：在命令行中运行 Decodo 抓取工作流。
* [**TypeScript SDK**](https://help.decodo.com/docs/cn/typescript-sdk.md)：将 Decodo API 集成到 TypeScript 和 JavaScript 项目中。
* [**Python SDK**](https://help.decodo.com/docs/cn/python-sdk.md)：将 Decodo API 集成到 Python 项目中。
* [**MCP 服务器**](https://help.decodo.com/docs/cn/mcp.md)：将 AI 智能体和兼容 MCP 的工具连接到 Decodo。
* [GitHub 仓库](https://github.com/Decodo/sdk-go)：查看 Go SDK 的源代码、示例和最新版本。

***

> [card] [支持](https://direct.lc.chat/12092754)
>
> 需要帮助或只是想打个招呼？我们的支持团队全天候为您服务。 \
> 您也可以随时通过电子邮件 [support@decodo.com](mailto:support@decodo.com) 联系我们。

> [card] [反馈](mailto:feedback@decodo.com)
>
> 找不到您要找的内容？请求一篇文章！ \
> 有反馈意见？分享您对我们如何改进的想法。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.