Inside the QuantumLayers API: Actions, Auth, and the Two Ways to Call It
The first post gave the map. This one walks the ground. Here is how the single AJAX endpoint actually behaves, how the three authentication options differ once you are minting tokens for real, and when to reach for raw API calls versus the bundled JavaScript Development Kit.
Picking Up Where the Overview Left Off
The previous post made the case for embedding QuantumLayers instead of rebuilding an analytics stack, and it sketched the shape of the API at arm’s length: one endpoint, three ways to authenticate, and a handful of action families. This post goes closer. It draws on the three reference pages that make up the developer documentation, namely the Developer Guide, the API reference, and the JDK reference, and it stays at a level where you can understand the design without reading every endpoint definition.
One thing worth stating up front, because it explains a lot of what follows. QuantumLayers has no separate REST service and no GraphQL layer. Every capability is a WordPress AJAX action, which means the entire product surface is a list of action names posted to one URL. That decision shapes how you authenticate, how you call endpoints, and how the JDK is built on top of them.
The Request Envelope
Every call is a form-encoded POST to wp-admin/admin-ajax.php. The action field names the operation, a Bearer token goes in the Authorization header, and the rest of the fields are parameters for that action. A request to draw a bar chart looks like action=ql_get_chart_data&dataset_id=42&chart_type=bar, and a request to list your datasets is just action=ql_get_dashboard_data with nothing else attached.
Responses share one envelope. Success comes back as { "success": true, "data": {...} }, and failure as { "success": false, "data": { "message": "..." } }. Because the shape never changes, your error handling can be written once and reused for every action. There is also a small distinction in how endpoints guard themselves. Public endpoints, such as reading a chart from a public dataset, accept an optional token and fall back to anonymous access. Everything that writes or analyzes requires a valid token. The guide names these two internal checks directly, so when a private endpoint rejects an anonymous call, the behavior is expected rather than mysterious.
Authentication, Now With the Details That Matter
The first post described three authentication paths in the abstract. The reference pages fill in the parts you actually have to get right, and the differences between the three come down to where the token originates and how long it lives.
The session token lives in the browser. After a user signs in through QuantumLayers, their token sits in localStorage under the key ql_session_token, and the JDK reads it with QLAuth.getSessionToken(). This only works on a page running in a browser context where that login already happened, so it fits embeds served from the QL origin itself. The session lasts thirty days and refreshes as the user stays active.
The third-party JWT is the path that makes cross-origin embedding work, and it is the one with real moving parts. The QL operator registers your application once, storing a provider slug, a display name, and a shared HMAC secret. Your backend then signs a short HS256 JWT whose header carries that provider slug as the kid and whose payload carries a stable user ID as sub, plus the user’s email and optionally their name. You post that token to ql_third_party_signin, QuantumLayers verifies the signature, finds or creates a shadow user keyed on the provider plus the subject, and returns an ordinary session token you use from then on. The reference shows this minting step in PHP and Node, both with a JWT library and with nothing but the language’s built-in crypto, so you are not forced to add a dependency to get started. The key discipline is that the kid in your header has to match the registered provider slug exactly, since that is how QL selects the secret to verify against.
The API token skips all of that. You create one on the API Tokens page, copy it once, since it is shown only at creation, and present it as a Bearer token on every request with no sign-in call first. This is the option for server-side work, and its lifetime is yours to choose, from thirty days up to one that never expires for fixed infrastructure. The one habit worth forming early is treating the value like any other secret, because a non-expiring token is a standing key to your data.
A short way to choose: use the session token when your page already lives inside a QL login, use the JWT when your own backend needs to provision users on the fly without ever showing them a QL screen, and use the API token when there is no browser in the picture at all. Both the JWT exchange and the API token ultimately hand you the same kind of Bearer token, so everything downstream of authentication is identical regardless of how you got there.
What the Endpoints Actually Give Back
The API groups into the families the first post named, but the reference makes clear how much work each one absorbs on your behalf. A few are worth calling out because they change what you have to build.
Charting returns finished Chart.js configuration objects. You send a dataset ID, a chart type, and a column mapping, and you receive an object you can pass straight into new Chart(ctx, data). Filtering and aggregation happen server-side before the data ever reaches you, and the type-specific parameters are small: a bar chart wants a category column and value columns, a scatter wants an x and a y, a histogram just wants a column name and bins itself. There is also a recommendation endpoint that inspects a dataset, scores candidate charts, and returns a ranked set already rendered as configs, which is enough to fill a dashboard with nothing configured by hand.
Statistical analysis is where the depth shows. A single action returns per-column summaries with quartiles, skewness, and kurtosis. Another returns a full Pearson correlation matrix, cached for an hour so repeat calls are instant. Distribution analysis flags outliers using the standard inter-quartile fence and labels how far a column departs from normal. There is a principal component analysis that standardizes columns and returns explained variance and loadings, and a one-way ANOVA that reports F-statistics, p-values, effect sizes, and significance labels for every categorical-by-numeric pairing. These are things teams routinely get subtly wrong when they implement them by hand, and here they are one action away.
AI insights run in two stages. First a rule-based pass runs nine analyses in parallel, covering correlation, ANOVA, distribution, temporal trends, regression, categorical balance, categorical relationships, lagged cross-correlation, and multicollinearity. Everything carrying a p-value is then put through a Benjamini-Hochberg correction, so findings that only looked significant because many tests ran are dropped before you see them. If a model key is configured and the user’s token budget allows it, a second stage sends the surviving findings to a language model for a plain-language narrative. The statistical honesty is built in rather than bolted on, which is the whole point of the pipeline.
Datasets, reports, organizations, and the agent round out the surface. Ingestion covers CSV, SQL, REST, SFTP, Google Sheets, Kaggle, and merged datasets, and once a source is connected it becomes an ID you feed to everything else. Scheduled reports deliver recurring PDF or HTML summaries by email. Organization endpoints manage seats and shared datasets. The agent endpoint runs one turn of a conversational loop that can list data, chart it, and analyze it on its own, returning both the updated history and a final reply, so a chat surface is a matter of calling one action per user message and passing the history back each time.
Two Ways In: Raw Calls or the JDK
Everything above can be reached two ways, and they hit the same endpoints underneath. The choice is about how much plumbing you want to write versus how much you want to depend on.
Raw API calls suit anything without a browser, or a front end where you would rather write a thin client than pull in someone else’s. You post to the endpoint with whatever HTTP tool you already use, whether that is fetch, curl, or a server-side library in any language, and you parse the JSON envelope yourself. Nothing about this path asks you to load QuantumLayers JavaScript at all.
The JDK is a set of standalone browser modules published under a public path, each loadable with a plain script tag and no build step. The modules line up with the product’s surfaces: QLAuth for sign-in and token handling, QLUpload for CSV ingestion, QLDashboard for the dataset inventory, QLAnalytics for chart rendering and the statistical modals, QLInsights for the AI narrative panel, QLAgent for the conversational loop, and others for merging, reports, and organizations. They build the request, attach the Bearer token, and parse the response for you, which is the right trade when you want the same behavior QuantumLayers itself ships rather than reimplementing request plumbing.
Two ordering rules matter if you go the JDK route. Load jQuery first, because the modules depend on it, and load auth.js before any other QL module, because every one of them calls QLAuth.getSessionToken() to build its header. Chart rendering adds one more requirement: Chart.js and three plugins, for box plots, time axes, and matrix heatmaps, have to be present before analytics.js runs, or the affected chart types will not draw. The insights module leans on the analytics module for its embedded charts, so when you use both, analytics loads first. None of this is heavy, but the order is not optional.
A Realistic First Path Through
Putting the pieces together, a first integration follows a predictable arc. Your backend authenticates, by minting a JWT for a signed-in user or presenting an API token for a job, and receives a session token. You call ql_get_dashboard_data to list datasets and learn their IDs, since that is the ID everything downstream needs. You request a chart, a statistical summary, or an insight for one of those datasets, and you either render the returned Chart.js config yourself or let the JDK do it. That is a working feature, and nothing in it required you to build ingestion, write aggregation, or implement a significance test.
From there, growth is cheap because the request shape never changes. Adding correlation next to your bar chart is the same call with a different action. Turning a static dashboard into a conversational one is the same call pointed at the agent. The reference pages exist for the moment you need an exact parameter or response field, and this post is meant to get you to that moment already understanding how the whole thing fits together.
This is the second post in the QuantumLayers series on embedded analytics. Start with the Developer Guide for prerequisites and authentication, then go deep in the API reference for every endpoint and the JDK reference for every module. Start building at www.quantumlayers.com.