Skip to content
Back to skills

Dapi Request

ASecurity

Builds, validates and sends a request to any 3DAPI public API route from the live OpenAPI contract. Use whenever a skill needs to call 3DAPI (quote, poll, list orders, update status). Not for deciding what to send; the calling skill decides, this skill makes it correct and safe.

  • 6 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 16, 2026
ai-agentspythongobashapi

Works with

  • api

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned October 16, 2026

npx -y skills add 3DAPI-Inc/dapilot --skill dapi-request --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dapi Request?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dapi Request
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/3dapi-inc-dapi-request/badge)](https://www.skillsdirectory.com/skills/3dapi-inc-dapi-request)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dapi-request
description: Builds, validates and sends a request to any 3DAPI public API route from the live OpenAPI contract. Use whenever a skill needs to call 3DAPI (quote, poll, list orders, update status). Not for deciding what to send; the calling skill decides, this skill makes it correct and safe.
allowed-tools: Read, Bash, Write
---

# dapi-request

## When
Any time a skill needs to talk to dapi. Every 3DAPI call in this plugin goes
through `${CLAUDE_PLUGIN_ROOT}/scripts/dapi.py`; no skill assembles HTTP
requests in prose. Needs `DAPI_API_URL` and, to send, `DAPI_API_KEY`.

## Inputs
- The operation id (from `ops`), or the intent in words, which step 1 turns
  into an operation id.
- The values the caller wants to send: path params, query params, body.
- For a proposal that a person will execute: the work dir to write it to.

## Procedure
1. Find the operation. Run
   `$PY ${CLAUDE_PLUGIN_ROOT}/scripts/dapi.py ops` (add `--tag "Quotes"` to
   narrow). Pick the id whose summary matches the intent. If none matches,
   stop with `ok:false, reason: "no public route for <intent>"`. Do not
   improvise a path.
2. Read its contract. Run `dapi.py describe <op>`. Note `scope`, `gate`,
   the required params, `body_schema` and `example_body`.
3. Judge the payload. Map the caller's values onto the schema fields. Use
   only fields the schema declares; the server rejects unknown ones. Where
   the caller gave nothing for a required field, stop and say which field,
   rather than inventing a value.
4. Validate without sending. Write the body to `$WORKDIR/req.<op>.json` and
   run `dapi.py validate <op> --path k=v --query k=v --body <file>`. If
   `valid` is false, fix only what the `errors` list names and validate
   again. Two failed rounds means the inputs are wrong: stop with the errors.
5. Send, or propose. If `gate` is `auto`, run `dapi.py call <op> ...`. If
   `gate` is `propose`, run the same `call` without `--confirm`: it prints
   the exact request as a dry run and exits 0. Write that output to
   `$WORKDIR/proposal.<op>.json` and return `needs_human` with the command
   the person should run, with `--confirm` appended. Never pass `--confirm`
   yourself.
6. Interpret the result. `ok:true` with `status` 2xx is success; `body` is
   the response. Otherwise read `status` and `body`: 400 is a contract
   mismatch (go back to step 3 once), 401 or 403 is a key or scope problem
   (stop, report the `scope` from step 2), 404 is a missing resource (stop),
   429 is rate limiting (stop, report `rate_limit`), 5xx is 3DAPI's problem
   (stop, do not retry here; the orchestrator owns retries).

## Outputs
- `$WORKDIR/req.<op>.json` the body that was validated.
- `$WORKDIR/res.<op>.json` the full `call` output on success or failure.
- `$WORKDIR/proposal.<op>.json` for gated operations, the dry run.
- Result line: `{"ok":..., "outputs":[...], "needs_human":..., "reason":...,
  "summary": "<METHOD> <path> -> <status>"}`.

## Gate
The gate is per operation and lives in the `GATES` table in `dapi.py`.
Mutating operations not in that table are `propose`. This skill never
changes a gate and never passes `--confirm`. Read-only calls are `auto`.

## Failure
- Missing env: the script exits 2 with the reason. Pass it through, stop.
- Unknown operation: stop. The route does not exist for us.
- `valid:false` after two fixes: stop with the error list.
- Connection failed or 5xx: stop with the reason. No retry inside this skill.

## Do not
- Do not type a URL or path. The spec is the only source of routes.
- Do not add fields the schema does not declare, even if the intent seems
  to need them. Report the gap instead.
- Do not pass `--confirm`, ever.
- Do not log or write `DAPI_API_KEY` anywhere, including `log.md`.
- Do not call `spec --refresh` on every request. The cached spec is fine
  until a 400 suggests the contract moved.

## Reference
- `reference/surfaces.md` the two API surfaces, scopes, which routes mutate.
- `reference/quote-flow.md` the intake sequence: upload, create, poll.

`$PY` is `${DAPILOT_PYTHON:-python3}`.

Files in this skill

  • SKILL.md4 KB
  • eval/bad-create-quote.json148 B
  • eval/cases.md2.8 KB
  • eval/mock.py1.1 KB
  • eval/status.json119 B
  • reference/quote-flow.md1.5 KB
  • reference/surfaces.md2.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.