Local POIs (Search API)
Paid Local POIs proxy via x402 pay-per-use (HTTP 402).
Prerequisites: This skill requires x402-payment. Complete the setup steps before first use.
Two-step flow: This endpoint requires POI IDs from a prior web search.
- 1. Call
web-search with result_filter=locations to get POI IDs from INLINECODE2 - Pass those IDs to this endpoint to get full business details
Security: Documentation only — no executable code or credentials. Wallet/keys stay on your machine; never stored here.
Service URLs
| Role | Domain |
|---|
| API Provider | https://www.cpbox.io |
| Facilitator |
https://www.cppay.finance |
Endpoint (Agent Interface)
CODEBLOCK0
Payment Flow (x402 Protocol)
- 1. First request ->
402 Payment Required with requirements JSON - Sign & retry with
PAYMENT-SIGNATURE -> result JSON
With @springmint/x402-payment or x402-sdk-go, payment is automatic.
Quick Start (cURL)
Get POI Details
CODEBLOCK1
Multiple POIs with Location Headers
CODEBLOCK2
Note: POI IDs are opaque strings returned in web search locations.results[].id. IDs are ephemeral and expire after ~8 hours. The example IDs above are for illustration — fetch fresh IDs via web-search with result_filter=locations. Use --data-urlencode since IDs may contain =.
POI ID Cache & Invalidation
| Aspect | Policy |
|---|
| TTL | POI IDs are valid for approximately 8 hours from issuance. |
| Invalidation |
IDs cannot be refreshed or extended. After expiry, use
web-search with
result_filter=locations to obtain new IDs. |
|
Caching | You may cache POI details (hours, ratings, etc.) locally for display; do not cache IDs beyond 8 hours for reuse in
local-pois or
local-descriptions. |
|
Expired ID | Requests with expired IDs return empty or error results. Re-run the web search to get fresh IDs. |
Using with x402-payment
CODEBLOCK3
Parameters
| Parameter | Type | Required | Default | Description |
|---|
| INLINECODE16 | string[] | Yes | — | POI IDs from web search results (1-20) |
| INLINECODE17 |
string | No |
en | Language preference (2+ char language code) |
|
ui_lang | string | No |
en-US | UI language (locale code, e.g., "en-US") |
|
units | string | No | null |
metric (km) or
imperial (miles) |
Location Headers (Optional)
For distance calculation from user location:
| Header | Type | Range | Description |
|---|
| INLINECODE24 | float | -90.0 to 90.0 | User latitude |
| INLINECODE25 |
float | -180.0 to 180.0 | User longitude |
Response Fields
The response has type: "local_pois" and a results array of LocationResult objects:
| Field | Type | Description |
|---|
| INLINECODE29 | string | Business/POI name |
| INLINECODE30 |
string | Canonical URL for the location |
|
provider_url | string | Provider page URL |
|
type | string | Always
"location_result" |
|
id | string | POI identifier (opaque string, valid ~8 hours) |
|
description | string? | Short description |
|
postal_address.type | string | Always
"PostalAddress" |
|
postal_address.displayAddress | string | Formatted display address |
|
postal_address.streetAddress | string? | Street address |
|
postal_address.addressLocality | string? | City |
|
postal_address.addressRegion | string? | State/region |
|
postal_address.postalCode | string? | Postal/ZIP code |
|
postal_address.country | string? | Country code |
|
contact.telephone | string? | Phone number |
|
contact.email | string? | Email address |
|
rating.ratingValue | float? | Average rating (≥0) |
|
rating.bestRating | float? | Max possible rating |
|
rating.reviewCount | int? | Number of reviews |
|
rating.profile.name | string? | Rating provider name |
|
rating.profile.url | string? | Rating provider URL |
|
opening_hours.current_day | object[]? | Today's hours (
abbr_name,
full_name,
opens,
closes) |
|
opening_hours.days | object[][]? | Hours for each day of the week (same structure) |
|
coordinates | [float, float]? |
[latitude, longitude] tuple |
|
distance.value | float? | Distance from user location |
|
distance.units | string? | Distance unit (
km or
miles) |
|
categories | string[] | Business categories (default
[]) |
|
price_range | string? | Price indicator (
$,
$$,
$$$,
$$$$) |
|
serves_cuisine | string[]? | Cuisine types (restaurants) |
|
thumbnail.src | string? | Thumbnail image URL |
|
thumbnail.original | string? | Original image URL |
|
profiles | object[]? | External profiles (
name,
url,
long_name,
img) |
|
reviews.reviews_in_foreign_language | bool | Whether reviews in a foreign language are available |
|
pictures.results | object[]? | Photo thumbnails |
|
action | object? | Action to take — has
type (string) and
url (string) |
|
results | object[]? | Related web results (
LocationWebResult with
meta_url) |
|
timezone | string? | IANA timezone (e.g.,
America/Los_Angeles) |
|
timezone_offset | int? | UTC timezone offset |
Example Response
CODEBLOCK4
Getting POI IDs
POI IDs come from the Web Search API (web-search) with result_filter=locations:
CODEBLOCK5
Use Cases
- - Local business lookup: Retrieve full details (hours, contact, address) for POIs surfaced in web search
- Restaurant discovery pipeline: Search for restaurants, fetch POI details, filter by cuisine/rating/pricerange
- Business hours checker: Get openinghours for a business to determine if currently open
- Location-aware application: Combine with location headers to get distance calculations for nearby POIs
Notes
- - ID format: Opaque strings (use
--data-urlencode for cURL) - Units:
metric or imperial for distance measurement preference - Max IDs: Up to 20 IDs per request
本地兴趣点(搜索API)
通过 x402按次付费(HTTP 402)提供的付费本地兴趣点代理服务。
前置条件:此技能需要x402支付。首次使用前请完成设置步骤。
两步流程:此端点需要从先前的网络搜索中获取兴趣点ID。
- 1. 使用 result_filter=locations 调用 web-search,从 locations.results[].id 获取兴趣点ID
- 将这些ID传递给此端点以获取完整的商家详情
安全性:仅提供文档说明——不包含可执行代码或凭证。钱包/密钥保留在您的机器上;绝不在此存储。
服务URL
| 角色 | 域名 |
|---|
| API提供商 | https://www.cpbox.io |
| 协调方 |
https://www.cppay.finance |
端点(代理接口)
http
GET /api/x402/local-pois
支付流程(x402协议)
- 1. 首次请求 -> 返回 402 Payment Required 及需求JSON
- 签名并重试 附带 PAYMENT-SIGNATURE -> 返回结果JSON
使用 @springmint/x402-payment 或 x402-sdk-go 时,支付为自动完成。
快速开始(cURL)
获取兴趣点详情
bash
curl -s https://www.cpbox.io/api/x402/local-pois \
-H Accept: application/json \
-H Accept-Encoding: gzip \
-G \
--data-urlencode ids=loc4CQWMJWLD4VBEBZ62XQLJTGK6YCJEEJDNAAAAAAA=
多个兴趣点及位置头信息
bash
curl -s https://www.cpbox.io/api/x402/local-pois \
-H Accept: application/json \
-H Accept-Encoding: gzip \
-H X-Loc-Lat: 37.7749 \
-H X-Loc-Long: -122.4194 \
-G \
--data-urlencode ids=loc4CQWMJWLD4VBEBZ62XQLJTGK6YCJEEJDNAAAAAAA= \
--data-urlencode ids=loc4HTAVTJKP4RBEBZCEMBI3NG26YD4II4PATIHPDYI= \
--data-urlencode units=imperial
注意:兴趣点ID是网络搜索返回的 locations.results[].id 中的不透明字符串。ID是临时的,约8小时后过期。上述示例ID仅供说明——请通过 web-search 并使用 result_filter=locations 获取最新ID。由于ID可能包含 =,请使用 --data-urlencode。
兴趣点ID缓存与失效
| 方面 | 策略 |
|---|
| TTL | 兴趣点ID自颁发起约8小时内有效。 |
| 失效 |
ID无法刷新或延长。过期后,使用 web-search 并设置 result_filter=locations 获取新ID。 |
|
缓存 | 您可以在本地缓存兴趣点详情(营业时间、评分等)用于展示;但不要将ID缓存超过8小时以用于 local-pois 或 local-descriptions。 |
|
过期ID | 使用过期ID的请求将返回空结果或错误结果。请重新运行网络搜索以获取新ID。 |
配合x402-payment使用
bash
npx @springmint/x402-payment \
--url https://www.cpbox.io/api/x402/local-pois?ids=loc4CQWMJWLD4VBEBZ62XQLJTGK6YCJEEJDNAAAAAAA%3D \
--method GET
参数
| 参数 | 类型 | 必填 | 默认值 | 描述 |
|---|
| ids | string[] | 是 | — | 来自网络搜索结果的兴趣点ID(1-20个) |
| search_lang |
string | 否 | en | 语言偏好(2个以上字符的语言代码) |
| ui_lang | string | 否 | en-US | 界面语言(区域代码,如en-US) |
| units | string | 否 | null | metric(公里)或 imperial(英里) |
位置头信息(可选)
用于计算与用户位置的距离:
| 头信息 | 类型 | 范围 | 描述 |
|---|
| X-Loc-Lat | float | -90.0 至 90.0 | 用户纬度 |
| X-Loc-Long |
float | -180.0 至 180.0 | 用户经度 |
响应字段
响应包含 type: local_pois 和一个 LocationResult 对象的 results 数组:
| 字段 | 类型 | 描述 |
|---|
| title | string | 商家/兴趣点名称 |
| url |
string | 该位置的规范URL |
| provider_url | string | 提供商页面URL |
| type | string | 始终为 location_result |
| id | string | 兴趣点标识符(不透明字符串,约8小时有效) |
| description | string? | 简短描述 |
| postal_address.type | string | 始终为 PostalAddress |
| postal_address.displayAddress | string | 格式化显示地址 |
| postal_address.streetAddress | string? | 街道地址 |
| postal_address.addressLocality | string? | 城市 |
| postal_address.addressRegion | string? | 州/地区 |
| postal_address.postalCode | string? | 邮政编码 |
| postal_address.country | string? | 国家代码 |
| contact.telephone | string? | 电话号码 |
| contact.email | string? | 电子邮件地址 |
| rating.ratingValue | float? | 平均评分(≥0) |
| rating.bestRating | float? | 最高可能评分 |
| rating.reviewCount | int? | 评论数量 |
| rating.profile.name | string? | 评分提供商名称 |
| rating.profile.url | string? | 评分提供商URL |
| opening
hours.currentday | object[]? | 今日营业时间(abbr
name、fullname、opens、closes) |
| opening_hours.days | object[][]? | 一周中每天的营业时间(相同结构) |
| coordinates | [float, float]? | [纬度, 经度] 元组 |
| distance.value | float? | 与用户位置的距离 |
| distance.units | string? | 距离单位(km 或 miles) |
| categories | string[] | 商家类别(默认 []) |
| price_range | string? | 价格指示($、$$、$$$、$$$$) |
| serves_cuisine | string[]? | 菜系类型(餐厅) |
| thumbnail.src | string? | 缩略图URL |
| thumbnail.original | string? | 原始图片URL |
| profiles | object[]? | 外部资料(name、url、long_name、img) |
| reviews.reviews
inforeign_language | bool | 是否有外语评论可用 |
| pictures.results | object[]? | 照片缩略图 |
| action | object? | 要执行的操作——包含 type(string)和 url(string) |
| results | object[]? | 相关网络结果(包含 meta_url 的 LocationWebResult) |
| timezone | string? | IANA时区(如 America/Los_Angeles) |
| timezone_offset | int? | UTC时区偏移量 |
示例响应
json
{
type: local_pois,
results: [
{
type: location_result,
title: 公园地中海烧烤,
url: https://yelp.com/biz/park-mediterranean-grill-sf,
provider_url: https://yelp.com/biz/park-mediterranean-grill-sf,
id: