Power BI (Power Query)

🚧

Opt-in while the endpoint is in pilot

This endpoint only answers for organizations Padlet has enrolled. Enrollment is granted on the organization's owner. Being an admin is not enough. Email [email protected] to ask for enrollment. Until then every call answers 404, the same response an unknown organization gets.

📘

What you need

  • An API key from your developer settings.

  • The organization's hashid. Call GET /me?include=organizations — every organization your key can read is listed there by hashid.

This dataflow pulls Padlet analytics into Power BI and handles the wait for results for you. It loads two tables: Metrics, the organization's figures, and Users, its roster. The file is a Power BI dataflow definition, so Excel cannot import it.

Importing the dataflow

Download padlet-analytics.model.json.

  1. In a Pro workspace, choose + New → Dataflow. On that screen use the Import box and upload the file.
    Not Get data and not Add tables — those treat the JSON as a data source, and you end up with a table of the file's own fields. If you are already inside a dataflow, close it and start a new one; Import only appears on the new-dataflow screen.
  2. When asked for credentials, choose Anonymous. The key travels in a header.
  3. Open the dataflow, select Edit tables, and on the Home ribbon select Manage parameters. Set ApiKey to your API key and OrgId to your organization hashid. Select Save & close.
  4. Select Refresh now, then check Refresh history.

The two tables

TableRowsEdit
MetricsOne per requested metric. padletCount, postCount and active memberCount to startChange the metric list in the Metrics query. See the endpoint reference
UsersOne per current member, with their padlets, posts, comments and reactionsChange the options record in the Users query. See the endpoint reference

The Users query takes its filters as a record:

FieldValue
from, to"2026-01" and "2026-03". Send both or neither
status"active" or "inactive"
userTypeOne role, "teacher", or several, {"teacher", "admin"}
qSubstring of a name or email
sort"posts", "name", "lastActivityDate", and the other sortable columns
order"asc" or "desc"
perPageRows per request, up to 100. Lower it only to debug

The roster arrives a page at a time, and the query walks every page. At 100 rows a page and 60 requests an hour, one refresh can read about 6,000 members. Filter the roster if it is larger than that, or the walk stops with the 429 message below.

Scheduled refresh in the Power BI Service

Two things decide whether a schedule works:

Data source must not be dynamicThe dataflow uses a static base URL with the hashid in RelativePath. Keep it that way — a URL built by concatenation refreshes fine in Desktop, then fails in the Service
CredentialsThe key travels in a header, so the source authenticates as Anonymous. Set it once in the dataflow's settings, under data source credentials

Refresh has a time budget: 2 hours on Pro, 5 on Premium/PPU. Keep from and to fixed rather than rolling, so the figures come from cache instead of spending that budget waiting. Pro also caps a dataflow at 8 scheduled refreshes a day. The endpoint allows 60 requests an hour per API key and organization, and each poll counts as a request.

When something goes wrong

ResponseCause
401Key missing, revoked, or from a different environment
404Wrong hashid, the organization isn't enrolled, or the key lacks analytics access — all three look the same
400Metrics: unknown metric, invalid property value, a range over 24 months, a duplicate metric, or more than 50 resolved queries. Users: an unknown status, userType, sort or order value
415The body went out form-encoded. The dataflow's Content-Type header prevents this
429Over 60 requests in an hour for this key and organization. On the Users walk the dataflow raises a message naming the limit; filter the roster or raise perPage
Still pending after every attemptThe dataflow raises instead of loading a partial table. Pass a larger maxAttempts as a fourth argument in the Metrics query, or narrow the request
A query that will not loadRecords and lists in cells can't be loaded. Select scalar fields and declare their column types
"This dataset includes a dynamic data source"The URL was assembled by concatenation somewhere. Move the varying part into RelativePath