SuperAPI AI Directory

openydt-api-explorer

Coding & development

View repository

Updated 10-16 01:30

About this skill

openydt-api-explorer — Generic API fallback / interface exploration

CRITICAL: Before starting, MUST first use the Read tool to read ../openydt-shared/SKILL.md(authentication / profile / signature / status codes / rate limiting / security rules).openydt api It follows exactly the same signature, envelope, exit code, and rate limiting logic as first-class commands; do not execute any command without reading the shared foundation.

When to use this skill

The platform has many interfaces, among whichmost have been made into domain first-class commands(openydt <域> <命令>, with parameters already structured as flags), but there are still quite a few that have not been made first-class (for authoritative counts see make counts / INTERFACE_INDEX.md, do not memorize numbers). When the interface you want to callhas no dedicated subcommand, use this skill's generic fallback:

openydt api <cmd> --body '{...}'

api forany callable (direction=callable) business code cmd automatically signs and POST, covering all domains not named by first-class commands, for example:

  • cityOperationCoupon city operation coupons (create/issue city operation coupon templates)
  • thirdParkForBolian third-party parking lot payment access receipt
  • upward uplink data reporting receipt (such as asynSuccess)
  • community community access control (such as getAuthCommunities)
  • ad ad statistics,preferential/score points redemption,invoice invoices,ydtUser user authentication, etc.
  • interfaces that have a dedicated domain but whose sub-features have not been made first-class: monthly pass reservation/queueing (ticket·appointment), monthly pass authorized visitors (ticket·authorize), monthly pass document rules (ticket·certificate), vehicle tags (parking·tag:addCarTags/delCarTags) — the monthticket / record domain skills will point these to this skill, also use api to call (remember for write operations --yes)

These domains in catalog.json have included=false(no first-class command generated), but as long as direction=callable you can use api to call directly.

Selection order:first look for a first-class command(openydt <域> --help or the corresponding domain skill), if not found then use api fallback. First-class commands split parameters into flags, automatically determine read/write, and are less error-prone;api is "raw JSON direct send", more generic but you must ensure the body is correct yourself.

Usage: openydt api

# 1) 行内 JSON body(最常用)
openydt api getParkFee --body '{"parkCode":"1ZS7H5PQH9","carCode":"粤EJW962"}'

# 2) 无参接口可省略 body
openydt api getAuthParkCodes

# 3) 从文件读 body
openydt api getParkOnSiteCar --body-file ./body.json

# 4) 从 stdin 读 body(- 表示 stdin),适合管道 / 大 body
echo '{"parkCode":"PTD2YBBZ"}' | openydt api getParkOnSiteCar --body-file -
  • <cmd>: business code,is the cmd field in the catalog(such as getParkFee、createCityOperationCouponTemplate). Note it is cmd, not dir path.
  • --body and --body-file are mutually exclusive; if neither is given, an empty body is sent ({}), only suitable for interfaces without parameters.
  • body israw JSON: the CLI will first do JSON compact before using it for signing and sending (consistent with first-class commands), spaces inside strings such as "2019-04-16 00:11:25" will be preserved.
  • Parameter naming and nested structurecompletely copy the interface definition(see below for looking up parameters from the catalog); writing the wrong field name usually returns status=2 / resultCode=909 请求参数错误 or status=7 请求参数不完整。

--dry-run preview

If unsure about the body or before the prod environment, first use --dry-run to only printthe signed request to be sent(URL / sign / ts / the compacted body), not actually sent:

openydt api createCityOperationCouponTemplate --dry-run \
  --body '{"parkCodeList":["1ZS7H5PQH9"],"couponTemplate":{"name":"抵扣1元券","faceValue":1}}'

The example parkCode/time are documented test values (test only); copying the catalog's historical sampleBody will hit an invalid parking lot/expired validity period.

Write operations must use --yes (api and first-class commands share the write guard)

api and first-class commands now go throughthe same write guard——RunCall for catalog readwrite=write 's cmd, uniformly require --yes(or --dry-run):

  • omitting --yes will be blocked, it won't actually be sent; the system will prompt "This is a write operation, add --yes to confirm".
  • Global --read-only(or the environment variable OPENYDT_READ_ONLY=1), any write cmd (including api) is rejected unconditionally.
  • For any cmd that changes platform state (create/modify/delete, issue coupon, pay, open gate, report receipt, etc.), stillrecommend first using --dry-run to preview the signed request, confirm it's correct, then --yes actually send—double assurance, especially important in prod.
  • To determine whether a cmd is read or write: look at the catalog's readwrite field (see "Querying from the catalog" below). For idempotency/retry of write operations, see [[openydt-shared]]'s references/write-idempotency.md。
# 写操作(catalog readwrite=write),必须先 --dry-run 预览,再 --yes 实发
openydt api createCityOperationCouponTemplate --dry-run \
  --body '{"parkCodeList":["1ZS7H5PQH9"],"couponTemplate":{"name":"抵扣1元券","totalNum":2,"couponType":1,"faceValue":1,"validFrom":"2026-06-01 00:00:00","validTo":"2027-06-01 00:00:00"}}'

openydt api createCityOperationCouponTemplate --yes \
  --body '{"parkCodeList":["1ZS7H5PQH9"],"couponTemplate":{"name":"抵扣1元券","totalNum":2,"couponType":1,"faceValue":1,"validFrom":"2026-06-01 00:00:00","validTo":"2027-06-01 00:00:00"}}'

Query the catalog for available cmds and parameters

The interface list is in ../../catalog/catalog.json(absolute path /Users/zhoujw/develop/tmp/openydt-cli/catalog/catalog.json). Top-level structure {generatedFrom, count, interfaces:[...]}, key fields of each interface object:

Field Meaning
cmd Business code,directly used as openydt api <cmd> 's cmd
domain / dir Owning domain / doc path (for categorization only,not an input parameter of api)
direction callable= can be actively called / webhook= actively pushed by the platform (see next section,cannot be called)
readwrite read / write—determines whether to add --yes
included Whether it has been made into a first-class command;false means to use api as a fallback
excludeReason The reason it hasn't been made into a first-class command (out-of-scope-domain / deprecated / no-endpoint / vems-only etc.)
params Parameter definition array:name / required / type / desc / group(group being nonempty means the parameter is nested inside some sub-object)
sampleBody Official example request body—the best starting point for constructing --body , copy the field names then change the values
sampleResponse Example response, to help you anticipate the returned fields

Use jq / python3 to search (don't print the secret in the terminal; here we only query the list, no credentials involved):

# 按 cmd 看完整定义(params + sampleBody)
jq '.interfaces[] | select(.cmd=="createCityOperationCouponTemplate")' catalog/catalog.json

# 列出某个未点名域所有“可调用”的 cmd 及读写
jq -r '.interfaces[] | select(.domain=="cityOperationCoupon" and .direction=="callable") | "\(.cmd)\t\(.readwrite)\t\(.explain)"' catalog/catalog.json

# 全量“没做成一等命令但可调用”的接口(included=false 且 callable)
jq -r '.interfaces[] | select(.included==false and .direction=="callable") | "\(.domain)\t\(.cmd)\t\(.readwrite)"' catalog/catalog.json

# 只看某 cmd 的参数清单(含嵌套 group)
jq '.interfaces[] | select(.cmd=="createCityOperationCouponTemplate") | .params' catalog/catalog.json

Interfaces with included=false but direction=callable can still be called with api —common in city operation coupons, third-party parking lot access (thirdParkForBolian), uplink receipts (upward), community access control (community), ads/points/invoices/ydtUser and other "unnamed domains".—common in city operation coupons, third-party parking lot access (thirdParkForBolian), uplink receipts (upward), community access control (community), ads/points/invoices/ydtUser and other "unnamed domains".included=false only means "no dedicated command was generated"; it doesn't mean "cannot be called"; to judge whether it can be called, look at direction, and to judge whether --yes is needed, look at readwrite。

Construction flow: ① jq get the target cmd's sampleBody → ② copy the field names, check required/type/nesting per params → ③ --dry-run preview the signed request → ④ for write operations add --yes to formally send.

Quick error self-healing reference (common with api fallback)

Symptom Meaning Recovery action
status=9 接口不存在 cmd misspelled / this cmd is a webhook (cannot be called proactively) `jq '.interfaces[]
status=2 resultCode=909 / status=7 body field name/required field error According to the catalog, this cmd's params check required fields and nested groupitem by item, start with sampleBody start with
writing cmd missing --yes blocked with "this is a write operation, add --yes" RunCall write guard (shared by api and first-class commands) First --dry-run preview, confirm it is a write cmd then --yes

For common codes, exit codes, and retry semantics see [[openydt-shared]]; for idempotency keys see its references/write-idempotency.md。

webhooks that cannot be called (platform-initiated push)

In the catalog, direction=webhook interfaces (such as reportParkinglotChange parking space change report; for the count see make counts) areplatform-initiated POST to your receivercallbacks, with the direction opposite to callable:

  • the CLI cannot proactively call these cmds—they have no entry point for "your request to the platform",openydt api <webhook-cmd> is not correct usage (the platform does not provide an endpoint in that direction).
  • To receive such pushes, you need tobuild your own HTTP receiver (webhook receiver), register the callback address with the platform, and the platform will POST data in the form of sampleBody to you when the event occurs; your service is responsible for signature verification, processing, and returning as agreed (many uplink receipts correspond to a callable confirmation cmd in the upward domain, such as asynSuccess)。
  • How to distinguish: before calling, first jq '.interfaces[]|select(.cmd=="<cmd>")|.direction', if it is webhook then do not use api to call it; instead build your own receiver; only if it is callable should you use api。

Example

Check which callable cmds exist in an unnamed domain (read, purely queries the catalog, sends no request):

jq -r '.interfaces[] | select(.domain=="thirdParkForBolian" and .direction=="callable") | "\(.cmd)\t\(.readwrite)"' catalog/catalog.json

Start with sampleBody, preview first then send (write operation example; for a formal send add --yes):

# 1) 取示例 body
jq -r '.interfaces[]|select(.cmd=="createCityOperationCouponTemplate")|.sampleBody' catalog/catalog.json

# 2) 预览签名请求,确认无误
openydt api createCityOperationCouponTemplate --dry-run --body-file ./body.json

# 3) 正式发(写操作,必须 --yes)
openydt api createCityOperationCouponTemplate --yes --body-file ./body.json

Read interfaces can be called directly (no --yes needed):

echo '{}' | openydt api getAuthCommunities --body-file -   # community 域,readwrite=read