datawrapper — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited datawrapper (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Create and publish Datawrapper charts and maps via REST API.
Auth: Authorization: Bearer $DATAWRAPPER_API (env var — never print the value). Base URL: https://api.datawrapper.de/v3
curl -s -o /dev/null -w "%{http_code}" \
"https://api.datawrapper.de/v3/me" \
-H "Authorization: Bearer $DATAWRAPPER_API"200 → key is valid, proceed.401 or 000 → key is missing or invalid. Stop and tell the user:"DATAWRAPPER_APIis not set or invalid. Set it withexport DATAWRAPPER_API=<token>(Linux/macOS) or$env:DATAWRAPPER_API='<token>'(PowerShell)."
Do NOT proceed past a non-200 — all subsequent calls will fail silently.
| Visualization | type value |
|---|---|
| Stacked bar | d3-bars-stacked |
| Grouped bar | d3-bars |
| Line | d3-lines |
| Scatter | d3-scatter-plot |
| Pie/donut | d3-pies |
| Choropleth map | d3-maps-choropleth |
| Locator map | locator-map |
Always read the relevant reference file before starting — each file contains the exact step sequence, mandatory properties, and known pitfalls.
CHART_ID=$(curl -s -X POST "https://api.datawrapper.de/v3/charts" \
-H "Authorization: Bearer $DATAWRAPPER_API" \
-H "Content-Type: application/json" \
-d '{"title": "My title", "type": "<type>"}' \
| jq -r '.id')
echo "Chart ID: $CHART_ID"Always capture the id — needed for all subsequent calls. Print it immediately.
curl -s -X PUT "https://api.datawrapper.de/v3/charts/$CHART_ID/data" \
-H "Authorization: Bearer $DATAWRAPPER_API" \
-H "Content-Type: text/csv" \
--data-binary @/path/to/data.csvcurl -s -X PATCH "https://api.datawrapper.de/v3/charts/$CHART_ID" \
-H "Authorization: Bearer $DATAWRAPPER_API" \
-H "Content-Type: application/json" \
-d '{ "metadata": { ... } }' \
| jq -r '.id // .'PATCH does a deep merge — each call merges into existing metadata. Old keys persist. To fully replace a nested object, include ALL its keys in a single PATCH call, or create a fresh chart.
curl -s -X POST "https://api.datawrapper.de/v3/charts/$CHART_ID/publish" \
-H "Authorization: Bearer $DATAWRAPPER_API" > /dev/nullAlways wait at least 6 seconds after publish before exporting. Datawrapper's CDN takes a moment to update — exporting immediately returns the previous render. Use scale=2 to export at double resolution. Omit height so Datawrapper uses the natural chart height — avoids large blank areas on short charts.
sleep 6
curl -s "https://api.datawrapper.de/v3/charts/$CHART_ID/export/png?unit=px&width=1200&scale=2" \
-H "Authorization: Bearer $DATAWRAPPER_API" \
--output output.pngAlways read the exported PNG visually to verify it looks correct before reporting success.
After verifying the PNG, ask the user:
"The PNG has been saved locally. Do you want to delete the chart from Datawrapper?"
If yes:
curl -s -X DELETE "https://api.datawrapper.de/v3/charts/$CHART_ID" \
-H "Authorization: Bearer $DATAWRAPPER_API"If no, remind the user the chart is available at: https://app.datawrapper.de/chart/<CHART_ID>/visualize
Always include units of measure (number-append/number-prepend) when values have a unit — percentages, euros, kilometres, etc. An axis without a unit label is always wrong.
{
"metadata": {
"describe": {
"source-name": "Data source name",
"source-url": "https://source-url.com",
"intro": "Chart or map description",
"byline": "Author or organization",
"number-append": " %",
"number-format": "0.0"
},
"annotate": {
"notes": "Methodology notes, caveats"
}
}
}See references/chart.md for the full units-of-measure reference.
curl -s "https://api.datawrapper.de/v3/charts/$CHART_ID" \
-H "Authorization: Bearer $DATAWRAPPER_API" \
| jq '.metadata'Use this to debug when the output doesn't look right — verify what properties Datawrapper actually stored vs. what you intended to send.
curl -s -X DELETE "https://api.datawrapper.de/v3/charts/$CHART_ID" \
-H "Authorization: Bearer $DATAWRAPPER_API"Useful when iterating: delete a broken chart and start fresh to avoid deep-merge conflicts from previous PATCH calls.
If something doesn't render correctly via API, the user can inspect and fix it at https://app.datawrapper.de/chart/<ID>/visualize. After manual edits, read back the config via GET to make it reproducible via API.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.