Universal API Client
BroadSQL can import an HTTP API's definition from a Bruno collection and call it directly, reusing the same workbench you already use for databases.
What this is for
Many day-to-day investigations involve both a database and the application/API in front of it. Universal API Client lets you import an existing Bruno collection once, then browse and call its endpoints from BroadSQL - no separate tool, no re-entering URLs, headers, or credentials.
Every commonly used HTTP method is executable: GET, HEAD, POST, PUT, PATCH, and DELETE. The one exception is OPTIONS, which is imported and visible like any other verb but cannot be executed - see Supported HTTP methods and What this release does not do.
An API does not have to come from Bruno at all. CONFIG API (see Configuring APIs with CONFIG API below) is a graphical window for building and maintaining an API entirely by hand: environments, base URLs, variables, authentication, folders, and endpoints, then calling EXECUTE API ENDPOINT against whatever you configured, exactly as if it had been imported.
Supported HTTP methods
| Method | Execution |
|---|---|
GET | Supported |
HEAD | Supported |
POST | Supported |
PUT | Supported |
PATCH | Supported |
DELETE | Supported |
OPTIONS | Not supported |
Every method, supported or not, is imported, persisted, and shown by SHOW ENDPOINTS/`SHOW API ENDPOINTS (the EXECUTABLE` column reflects this table exactly); only execution is restricted. Attempting to execute OPTIONS (or any other/unrecognized method) is refused before any network request, naming the method: see Executing an unsupported method or body.
Importing a Bruno collection
Export your collection from Bruno as a bundled OpenCollection YAML file (a single .yml file - this is the format Bruno itself produces when you choose a single-file export), then import it:
IMPORT API BRUNO "C:\bruno\my-api.yml" MYAPI;
MYAPI is the identifier you choose for this API inside BroadSQL. The command reports what was imported:
API imported: My Service
Environments: created 3, updated 0
Folders: created 12, updated 0
Endpoints: created 87, updated 0
Re-running the same command against an updated export of the same collection is safe: an endpoint, folder, or environment already known from a previous import is updated in place; a new one is added; nothing already imported is ever deleted just because it disappeared from the source file. You never need to re-enter anything by hand.
Directory-based (multi-file) Bruno projects are not read yet, only a single bundled YAML file.
Configuring APIs with CONFIG API
CONFIG API opens a graphical configuration window for the whole API catalog, the same way CONFIG does for database connections. It is a configuration tool only, never an execution workbench: there is no Execute button, no response viewer, and no request history here. Everything described below can be set up entirely by hand, without ever importing a Bruno file, and everything imported through `IMPORT API BRUNO` is immediately visible and editable in this same window.
Windows only, and only while connected to $CDF, exactly like CONFIG.
The window is a list of APIs on the left; the selected API's configuration on the right, across five tabs:
- General: name, description, and (for an imported API) where it came from and when it was last imported.
- Environments: every environment this API can run against (Development, Staging, Production, and so on), each with its own Base URL and its own variables.
Duplicatecopies an environment, including its secrets, so the common "duplicate Development, then change the Base URL and credentials" workflow needs no re-entry of everything else. - Authentication: the API's default authentication, used by every endpoint that does not set its own and is not inside a folder that sets one.
- Variables & Headers: API-wide variables and headers, available to every endpoint.
- Endpoints: a folder tree on the left, an editor on the right for whichever folder or endpoint is selected. The endpoint editor's General section shows the endpoint's system-managed numeric ID (not editable) alongside its name, method, path, folder, and alias, so you never need another command just to find the ID
EXECUTE API ENDPOINTexpects.
A secret value (a token, a password, a client secret) is always masked in every table; a "Show values" checkbox reveals it deliberately, the same convention BroadSQL already uses for database passwords.
Creating an API by hand
+ New API asks for an identifier and a name, then creates the API immediately. From there:
- Open the Environments tab and create an environment (for example,
Production), entering its Base URL. - Open the Authentication tab if the whole API shares one authentication scheme, or leave it set to
Inherit/Noneand configure authentication per folder or per endpoint instead. - Open the Endpoints tab, use
New Folderto group related endpoints if useful, thenNew Endpointto create one: name, HTTP method, URL (which may reference${baseUrl}or any other variable), andSave endpoint.
No internal identifier, source key, or database table is ever exposed; everything is named the way you already name it in the GUI.
Base URL
The environment editor shows Base URL as its own prominent field, never buried in the variable table below it. Internally it is still the ordinary baseUrl variable every endpoint template can reference (${baseUrl}/users), so changing it in the GUI immediately changes what every endpoint in that environment resolves to, whether the endpoint's URL uses ${baseUrl} explicitly or was created as a bare relative path.
Authentication and Inherit versus None
Authentication can be set at three levels: the API itself, a folder, or one endpoint. Inherit means "use whatever the next level up defines" and is the default for a newly created folder or endpoint. None is different: it explicitly turns authentication off at that level, even if a folder or the API above it defines one. The GUI always shows which of the two is in effect; it is never left ambiguous.
Supported types: Basic, Bearer token, API key (header or query), and OAuth2 Client Credentials. An authentication scheme imported from Bruno that this release cannot execute (Digest, NTLM, and similar) is shown as "Unsupported", read only, with the original type named, so it is never silently discarded or misrepresented as "no authentication".
Endpoint aliases
Every endpoint may optionally carry a BroadSQL alias, a short stable name such as DO_ORDER, set in the endpoint's General tab. An alias is entirely separate from the endpoint's display name and from its Bruno import identity:
- It is never generated automatically, on import or otherwise. You decide which endpoints, if any, get one.
- It survives a Bruno re-import untouched, even when the re-import updates the endpoint's name, URL, method, or anything else about it.
- It must be a valid identifier (letters, digits, and underscores, not starting with a digit) and must be unique within the API it belongs to. The same alias may be reused by a different API (for example,
PINGMAILcan name one endpoint inDESKand an unrelated endpoint inCRMat the same time), sinceRUNandEXECUTE API ENDPOINTalways resolve an alias within one named API. - Deleting the endpoint frees its alias immediately for reuse elsewhere, even within the same API.
The alias is what RUN and EXECUTE API ENDPOINT accept in place of the numeric endpoint id (see "Running an endpoint interactively" and "Executing an endpoint" below), and also exists for a possible future scripting statement that would call a configured endpoint by this name (for example, a future CALL DO_ORDER(...)); that statement does not exist yet in this release.
Importing and exporting Bruno YAML
Import Bruno YAML and Export Bruno YAML, at the bottom of the API list, do the same thing as IMPORT API BRUNO and the export described below, with a preview before import and a scope/secret choice before export.
Exporting to Bruno YAML
An API configured in BroadSQL, whether imported from Bruno or built entirely by hand, can be exported back to a real bundled OpenCollection YAML file that Bruno itself can open, through CONFIG API's Export Bruno YAML button (there is no separate CLI export command in this release). You choose which environments to include (all, by default) and whether to include secret values.
Secret values are excluded by default. A secret variable, header, or credential is written to the file without its value at all, never as an empty string and never as a fake masked value standing in for the real one; every non-secret part of the configuration exports normally. Including real secret values requires explicitly turning that on and confirming a warning that the file will then contain plaintext credentials.
An explicit None authentication round-trips correctly. Setting None (as opposed to leaving it on Inherit) exports as an explicit "no authentication" entry and comes back as None on re-import, never as an unrecognized/unsupported type: Inherit and explicit None remain distinguishable throughout.
The BroadSQL alias is never exported. OpenCollection has no field for it, and BroadSQL does not invent one, to avoid producing a file that looks like standard Bruno YAML but is not. An alias assigned in BroadSQL therefore survives a re-import into the same BroadSQL installation, but not a round trip through an exported file into a different installation.
A structured request body (form-urlencoded or multipart form data) is edited and re-exported as its underlying data rather than through a dedicated field-by-field table in this release; every field, value, and piece of metadata is still preserved exactly, only the editing experience is plainer than a purpose-built table would be.
If an imported endpoint's authentication cannot be represented exactly in OpenCollection (an unsupported type such as Digest), the export still proceeds and clearly lists which endpoint's authentication could only be approximated, rather than silently producing a file that looks correct but is not.
Environments
Every environment defined in the Bruno collection (Development, Staging, Production, ...) becomes a separate, selectable environment in BroadSQL. The same imported endpoint resolves differently depending on which environment you execute it under - changing environment never changes the endpoint definition itself.
SHOW API ENVIRONMENTS MYAPI;
lists every environment and its base URL. Environment variables that are secret (tokens, client secrets, ...) are never displayed by any command.
Connecting to an API session
CONNECT API MYAPI:Development;
establishes an active API session context, independent of and coexisting with any SQL database connection:
API MYAPI connected using environment Development.
Once connected, RUN and SHOW ENDPOINTS (below) use this API and environment without repeating them on every command. CONNECT API never closes or replaces the current database connection; connecting to a database with CONNECT <id> never clears an active API context either: the two are entirely independent, exactly like BroadSQL's connection and login concepts already are for SQL alone.
The prompt shows both when both are active:
$CDF [API MYAPI:Development]>
and just the API context when no database connection is active:
[API MYAPI:Development]>
An unknown or inactive API/environment, or a malformed <api>:<environment> target (a missing colon, a missing API name, or a missing environment name), is refused with a clear message; the previous API context, if any, is left unchanged.
Deactivating the currently connected API afterward (through CONFIG API, in another window) does not clear the session context by itself, but it does not remain usable through it either: RUN and `SHOW ENDPOINTS` revalidate the API's active status on every call and refuse it, naming it as inactive, the same way EXECUTE API ENDPOINT already does for an API named directly. DISCONNECT API and reconnect once it has been reactivated.
DISCONNECT API;
clears only the active API session context. The database connection, if any, is completely unaffected:
$CDF [API MYAPI:Development]> DISCONNECT API;
$CDF>
If no API context is active, DISCONNECT API does nothing.
Browsing endpoints
SHOW ENDPOINTS;
lists every endpoint of the active CONNECT API context, as a table:
+----+------+----------------+----------------+------------------+--------+------------+
| ID | VERB | FOLDER | PATH | NAME | ALIAS | EXECUTABLE |
+----+------+----------------+----------------+------------------+--------+------------+
| 5 | GET | Users | /users/{id} | Get User | | YES |
| 6 | POST | Users | /users | Create User | | NO |
| 12 | GET | Users / Search | /users/search | Advanced Search | SEARCH | YES |
+----+------+----------------+----------------+------------------+--------+------------+
3 endpoints
Without an active API context, use the equivalent explicit form instead, naming the API directly:
SHOW API ENDPOINTS MYAPI;
Both accept the same optional filters, in either order:
SHOW ENDPOINTS VERB GET;
SHOW ENDPOINTS MATCH search;
SHOW ENDPOINTS VERB GET MATCH search;
VERB <verb> matches the HTTP method exactly, case-insensitively. MATCH <keyword> is a case-insensitive substring search across the folder path, path, name, and alias combined. A filter that matches nothing reports an empty result, never an error.
Every HTTP method is listed, regardless of whether it can execute (EXECUTABLE shows NO only for OPTIONS and anything unrecognized, see Supported HTTP methods); an endpoint is never hidden merely because its verb isn't executable. The ID column (not the endpoint's display name, which is not guaranteed unique across folders) or, if one is set, the ALIAS column, is what you pass to RUN or EXECUTE API ENDPOINT.
Executing an endpoint
EXECUTE API ENDPOINT MYAPI 5 Development;
or, using an assigned alias instead of the numeric id:
EXECUTE API ENDPOINT MYAPI SEARCH Development;
resolves the endpoint's URL, query and path parameters, headers, and request body (see Request bodies below) against the selected environment, applies whichever authentication applies to it (see below), sends the request, and displays the result:
API: My Service
Environment: Development
Endpoint: GET Get User
GET https://dev.example.com/users/42
HTTP 200
Duration: 143 ms
Content-Type: application/json
{
"id": 42,
"name": "Alice"
}
A JSON object is pretty-printed as shown above. A JSON array of objects, however, is displayed as a table (see "Tabular results" below). A non-JSON textual response (plain text, HTML, XML) is shown as-is. A response BroadSQL cannot safely display as text is shown as size/content-type metadata only, never as raw bytes. Any HTTP status is displayed the same way: a successful write commonly returns 200, 201, 202, or 204, and a 204 No Content (typical for DELETE) is shown cleanly with no body section, never as an error. An HTTP error response (404, 401, 500, ...) is shown exactly like a successful one - the status and body are what you came to see; BroadSQL never confuses a real HTTP response, whatever its status, with a transport/network failure (a connection refused, a DNS failure, a timeout), which is reported separately and always before any status/body could exist.
If a value the request needs (a variable, a path segment) cannot be resolved, execution stops before any network request is made, naming exactly what is missing.
Request bodies
A POST/PUT/PATCH endpoint (or a DELETE endpoint that happens to need one) sends whatever body is configured for it in CONFIG API, interpolated through the same variable scope as the URL, query, path, and headers:
{
"name": "{{CUSTOMER_NAME}}",
"email": "{{CUSTOMER_EMAIL}}"
}
executes with {{CUSTOMER_NAME}}/{{CUSTOMER_EMAIL}} (or the ${...} compatibility form) replaced by their resolved values, exactly like everywhere else {{variable}} is used: see Variables. BroadSQL substitutes the configured text; it does not parse or rebuild the body as a JSON object, so the result is exactly what the substitution implies. If an interpolated value happens to make the body invalid JSON (for example, a value containing an unescaped "), BroadSQL still sends it as configured, the same textual-substitution behavior already used for URLs and headers, not a new validation layer, and the server's own response reports the problem.
Only a body configured as plain JSON, text, XML, or a SPARQL query can currently be sent; this is what CONFIG API's Body tab calls the json/text/xml/sparql modes. A structured body (form-urlencoded or multipart-form) is stored and preserved losslessly (round-trips through Bruno import/export and remains editable in CONFIG API) but cannot be executed yet, see Executing an unsupported method or body. CONFIG API's structured-body editor remains the raw canonical JSON text described in Configuring APIs with CONFIG API; this release does not add a field-by-field editor for it.
A request body is entirely optional: an endpoint with no body configured sends none, regardless of its HTTP method. DELETE commonly has none, but a POST/PUT/PATCH with nothing configured sends none too, and a GET with a body configured (unusual, but not prevented) would send it. BroadSQL follows what is configured, not a stereotype about the verb.
If no Content-Type header is already configured, BroadSQL sets a sensible default for the body's mode (application/json, text/plain, application/xml, or application/sparql-query); an explicit, configured Content-Type header always takes precedence.
The request body itself is never echoed anywhere in BroadSQL's own output, only the response is shown, so a secret value resolved inside a body is sent to the server correctly but never appears on screen, in a log, or in generated documentation.
Running an endpoint interactively (RUN)
Once CONNECT API has established an active session context, RUN is the interactive shorthand:
CONNECT API MYAPI:Development;
RUN 5;
RUN SEARCH;
RUN SEARCH RAW;
RUN resolves the numeric id or alias, the API, and the environment from the active session context, then executes the endpoint exactly as EXECUTE API ENDPOINT would with those same three values - semantically equivalent in every respect: authentication, variable resolution, tabular rendering, RAW, and PULL API RESULT capture all behave identically either way, including when the active environment's name contains a space. RUN requires an active API session context; without one, it reports the same message as any other command that needs one, naming CONNECT API as the fix.
The explicit EXECUTE API ENDPOINT <api> <endpointId-or-alias> <environment> form shown above remains fully supported and is the better choice for scripts and self-contained, non-interactive commands: it never depends on session state, so it means exactly the same thing regardless of what, if anything, is currently connected.
Tabular results
When a JSON response is naturally table-shaped, BroadSQL displays it as a table instead of pretty-printed JSON:
EXECUTE API ENDPOINT MYAPI 7 Development;
API: My Service
Environment: Development
Endpoint: GET List Users
GET https://dev.example.com/users
HTTP 200
Duration: 98 ms
Content-Type: application/json
id|name |
--|-----|
1 |Alice|
2 |Bob |
2 rows.
This applies to four shapes: an array of objects (one column per key, in first-seen order across every element; a row missing a key is shown with a blank cell rather than shifting the other columns), a single object (a one-row table), an empty array (a table with zero rows and zero columns), and an array of plain values such as numbers or strings (a single column named VALUE, one row per element). A nested object or array inside a cell is shown as compact JSON text, never split into extra columns or rows. Any other JSON shape, such as an array mixing objects with plain values, or a response that is not JSON at all, is displayed exactly as before this feature existed: pretty-printed JSON, or raw text.
Displaying a result as a table never discards the original response body; the underlying data behind the table is exactly what the server returned.
To always see the pretty-printed JSON or raw text, regardless of shape, append RAW:
EXECUTE API ENDPOINT MYAPI 7 Development RAW;
Executing a write method
A POST/PUT/PATCH/DELETE endpoint executes exactly like a GET, using its configured method, request body, and headers:
CONNECT API MYAPI:Development;
SHOW ENDPOINTS VERB POST MATCH customer;
+----+------+-----------+---------------+----------------+----------------+------------+
| ID | VERB | FOLDER | PATH | NAME | ALIAS | EXECUTABLE |
+----+------+-----------+---------------+----------------+----------------+------------+
| 21 | POST | Customers | /customers | Create Customer| CREATECUSTOMER | YES |
+----+------+-----------+---------------+----------------+----------------+------------+
1 endpoint
RUN CREATECUSTOMER;
API: My Service
Environment: Development
Endpoint: POST Create Customer
POST https://dev.example.com/customers
HTTP 201
Duration: 118 ms
Content-Type: application/json
{
"id": 501,
"status": "created"
}
The request body configured for CREATECUSTOMER (for example {"name": "{{CUSTOMER_NAME}}"}) was interpolated and sent, exactly as described in Request bodies. Updating or removing the same resource works the same way, only the endpoint's own configured method/path/body changes what is sent:
RUN UPDATECUSTOMER;
PATCH https://dev.example.com/customers/501
HTTP 200
Duration: 96 ms
...
RUN DELETECUSTOMER;
DELETE https://dev.example.com/customers/501
HTTP 204
Duration: 74 ms
Executing an unsupported method or body
EXECUTE API ENDPOINT MYAPI 6 Development;
against an OPTIONS-method endpoint refuses cleanly, before any request reaches the target server:
Execution refused.
Method OPTIONS is not enabled for execution in this release.
The same happens for an endpoint whose body mode is form-urlencoded or multipart-form (see Request bodies):
Endpoint 'Upload Attachment' has a 'multipart-form' request body, which this release cannot execute
(only json/text/xml/sparql bodies can be sent). The endpoint and its body remain fully visible and
editable in CONFIG API.
In both cases, the endpoint stays fully visible and configurable in the catalog and in CONFIG API; only execution is refused.
Executing an inactive API, endpoint, or environment
Deactivating an API, an endpoint, or an environment (via CONFIG API) leaves it fully visible for configuration/reactivation, but refuses execution, naming it as inactive rather than as not found:
Endpoint id 7 for API 'MYAPI' is inactive. Reactivate it first (CONFIG API), or use SHOW API ENDPOINTS
MYAPI to check its status.
Reactivate it from CONFIG API, or with the endpoint's Reactivate action, and execution works normally again, provided its alias, if it has one, has not since been claimed by a different active endpoint (see "Endpoint aliases" above); a reactivation that would create a duplicate alias is refused the same way a conflicting save would be, leaving the endpoint inactive.
Exporting API results
The last EXECUTE API ENDPOINT result held in memory can be pulled into BroadSQL's normal export/local snapshot machinery with PULL API RESULT TO ... - the direct sibling of PULL / TO ..., which does the same for the last SQL query held in memory (see export.md, "Exporting an API execution result", for the full grammar and every destination kind):
EXECUTE API ENDPOINT MYAPI 7 Development;
id|name |
--|-----|
1 |Alice|
2 |Bob |
2 rows.
PULL API RESULT TO WORKCOPY.USERS AS H2;
2 row(s) pulled into WORKCOPY.USERS (table dropped and recreated).
The same result can also be exported to a spreadsheet tab or a flat file:
PULL API RESULT TO REPORT.USERS AS XLSX;
PULL API RESULT TO USERS AS CSV;
This works for any tabular result, not only an array of objects like the example above - a single object becomes a one-row table, an array of plain values becomes a single VALUE column, and so on (see "Tabular results" above for the exact shape rules). Every exported column is text (VARCHAR); there is no numeric/ date typing for an API result this release, since the API result was never typed to begin with. MODE APPEND is not supported for this source - only a full MODE OVERWRITE (the default). AS JSON exports the flattened tabular shape (its columns), not the original raw API response body - the raw body is unaffected either way.
A result held in memory is always the last successful execution only: any later execution attempt that does not itself complete successfully (a write-method refusal, an unresolved variable, unsupported authentication, an inactive entity, or a network error) clears it immediately, so PULL API RESULT correctly reports nothing to export rather than silently re-exporting an earlier, unrelated result. This applies identically whether the attempt was made through EXECUTE API ENDPOINT or through RUN - including a RUN that fails only because no API session context is active (for example, right after DISCONNECT API):
PULL API RESULT TO WORKCOPY.USERS AS H2;
PULL API RESULT: no API execution result held in memory - run EXECUTE API ENDPOINT first.
Authentication
Whatever authentication the Bruno collection defines is imported and works automatically - nothing needs to be reconfigured in BroadSQL. Authentication can be set on the whole API, on a folder (inherited by every endpoint inside it), or on one endpoint specifically; a more specific setting always overrides a less specific one, and an endpoint explicitly configured with no authentication is never given one it didn't ask for.
Supported and executable in this release:
- No authentication
- HTTP Basic
- Static Bearer token
- API key, in a header or a query parameter
- OAuth2 Client Credentials (the access token is fetched automatically, cached in memory, and refreshed before it expires - never written to disk)
A credential that references an environment variable (the normal Bruno pattern, e.g. a Bearer token set to a variable) resolves against whichever environment you selected - switching environment switches credentials with it.
Other authentication schemes a Bruno collection might use (Digest, NTLM, OAuth1, AWS Signature, OAuth2 Authorization Code or Password grants) are imported and preserved, but this release cannot execute them: attempting to run such an endpoint is refused, naming the original authentication type, rather than silently sending the request unauthenticated.
Variables
A variable is referenced inside a URL, header value, query/path parameter value, request body, or authentication property with:
{{variableName}}
for example {{baseUrl}}/users?key={{KEY}}. This is the preferred syntax, matching Bruno's own convention, and is what CONFIG API and generated examples use.
${variableName} remains fully supported, for compatibility with configuration created or imported before this syntax was introduced:
${variableName}
A single URL, header, or parameter may freely mix both forms; both are resolved identically, and either fails the same way if the variable cannot be resolved: execution stops before any network request is made, naming exactly which variable is missing.
Variable names are matched case-sensitively. A variable saved as KEY is referenced as {{KEY}}, not {{key}}: a differently-cased reference is treated as a different, unresolved name.
Scope and precedence
A variable may be defined at several levels; the most specific one that defines a given name wins:
API variables
-> environment variables (the selected environment only)
-> folder variables (root to leaf, along the endpoint's folder chain)
-> endpoint variables
An API-level variable is the broadest scope: it is sometimes called a "global" variable for the API, since it applies regardless of which environment or folder the endpoint sits in. A variable defined again at a more specific scope (environment, then folder, then endpoint) simply shadows the same name at every broader scope; it does not need to be re-declared everywhere.
Headers and query/path parameters are not part of this variable-precedence chain: a header or parameter is resolved after variable substitution, in its own separate precedence (API default, then folder, then endpoint, then whatever authentication adds), unrelated to where the *variable values themselves* were defined.
A complete example
An API-level (global) variable:
KEY = DESK
An endpoint's query parameter:
key = {{KEY}}
Executing that endpoint resolves the parameter to the variable's value:
...?key=DESK
Changing environment never changes this, unless an environment-level variable named KEY (which would override the API-level one for that environment) or a folder/endpoint-level one is also defined.
baseUrl
baseUrl is an ordinary environment-scope variable, not a separate mechanism: it is simply the variable name BroadSQL (and Bruno) use, by convention, for an environment's base server URL. Setting Base URL in the Environments tab of CONFIG API (see "Base URL" above) sets this variable; referencing {{baseUrl}} (or ${baseUrl}) inside an endpoint's URL resolves it exactly like any other variable. A manually-created endpoint that uses a bare relative path (/users, with no {{baseUrl}} at all) has the environment's Base URL prefixed automatically instead; both styles resolve correctly.
Secrets
A variable marked secret (a token, a password, a client secret) is masked in every table BroadSQL shows, and is never printed by RUN, EXECUTE API ENDPOINT, SHOW ENDPOINTS, or the CONNECT API confirmation message: only the API and environment names are shown there, never variable values. A secret is still fully usable in {{variable}}/${variable} references; masking only affects display.
SQL and API together
A database connection and an API session context can be active at the same time, and BroadSQL keeps running ordinary SQL against the database connection throughout; connecting to an API never closes or replaces it:
$CDF> CONNECT API DESK:PROD;
API DESK connected using environment PROD.
$CDF [API DESK:PROD]> RUN PINGMAIL;
API: Desk Definition API
Environment: PROD
Endpoint: GET Check email service
GET https://desk.example.com/api/rest/emails/v1/ping?key=DESK
HTTP 200
Duration: 143 ms
OK
$CDF [API DESK:PROD]> SELECT COUNT(*) FROM CUSTOMER;
COUNT(*)
--------
1241
$CDF [API DESK:PROD]> PULL API RESULT TO PING_RESULT AS CSV;
1 row(s) pulled into PING_RESULT.csv.
$CDF [API DESK:PROD]> DISCONNECT API;
$CDF>
The same coexistence holds for a write endpoint: the database connection is no more affected by a POST/PATCH/DELETE than by a GET:
$CUSTOMERS_DB> CONNECT API CRM:TEST;
API CRM connected using environment TEST.
$CUSTOMERS_DB [API CRM:TEST]> RUN CREATECUSTOMER;
API: CRM Service
Environment: TEST
Endpoint: POST Create Customer
POST https://crm-test.example.com/customers
HTTP 201
Duration: 118 ms
{
"id": 501,
"status": "created"
}
$CUSTOMERS_DB [API CRM:TEST]> PULL API RESULT TO api_customer.CUSTOMERS AS H2;
1 row(s) pulled into api_customer.CUSTOMERS (table dropped and recreated).
$CUSTOMERS_DB [API CRM:TEST]> SELECT * FROM api_customer.CUSTOMERS;
ID |STATUS |
---|-------|
501|created|
$CUSTOMERS_DB [API CRM:TEST]> DISCONNECT API;
$CUSTOMERS_DB>
CUSTOMERS_DB, the SQL connection, is exactly as it was before CONNECT API ran; only the API session context changed.
What this release does not do
- Execute
OPTIONSendpoints, or any other/unrecognized HTTP method (imported and visible, not executable, whether imported or configured by hand inCONFIG API). - Execute an endpoint whose request body is configured as
form-urlencodedormultipart-form- both are stored and preserved losslessly, and remain editable inCONFIG API, but cannot be sent yet; onlyjson/text/xml/sparqlbodies can be executed. See Request bodies. - Provide a field-by-field editor for a structured request body; it remains raw canonical JSON text in
CONFIG API. - Validate that an interpolated request body is syntactically valid JSON before sending it; the configured text is substituted and sent exactly as it resolves, the same way URL/header substitution already works.
- Execute anything at all from
CONFIG APIitself; it is a configuration tool only. - Prompt for confirmation before running a
POST/PUT/PATCH/DELETEendpoint; runningRUN/EXECUTE API ENDPOINTagainst it is itself the instruction, exactly like every other command. - Run a future
CALL-style script statement using an endpoint alias; the alias exists today only as reserved, stable metadata for that future statement. - Import a directory-based (multi-file) Bruno project, only a single bundled YAML export.
- Import Postman collections or OpenAPI/Swagger specifications, or export to either format.
- Import or run Bruno scripts, pre/post-request automation, assertions, or tests.
- Relationalize or join an API result against another table server-side;
PULL API RESULT TO ... AS H2materializes it as a plain, unrelated table with text-only columns, ready for BroadSQL's normalJOINonce pulled, but no typing or relationalization happens automatically. - Automatically delete something from BroadSQL's catalog because it was removed from a re-imported collection; re-import only ever creates or updates, and the same applies to
CONFIG API's own manual editing. - Preserve a BroadSQL-assigned endpoint alias through an export followed by import into a different BroadSQL installation (it is never written to the exported file at all).
BroadSQL