Skip to main content
Imagine your dashboard says paid conversions fell 18%. Before changing a campaign or rewriting checkout, you need to answer: did customers stop buying, or did tracking break? In this tutorial, you will build a reusable analyst that investigates that question for you. The agent looks up the company’s metric definition, queries the data, checks what changed, and returns evidence. Next you ask about enterprise customers and get a chart from the same conversation. Once the Agent API customizations (managed connectors, versioned skills, instructions, and tools) are configured, your application sends a profile ID and a question. The profile supplies the saved configuration instead of making each application rebuild it. This is the Agent API call your client will make after setup. Your application does not supply the investigation’s SQL, a charting workflow, or the data-server credential.

What Agent API does for your application

You will configure the analyst once, ask it to investigate, then continue the conversation to get an enterprise chart. Each part of the experience uses an Agent API customization: Your application sends a profile ID and question to the Agent API agent. The agent queries the connector and sends a prompt to Sandbox. Sandbox determines what code to run and returns results. Shared files download separately. The agent chooses when to use its tools. It sends Sandbox a prompt, not a direct code-execution request. Sandbox determines what runs; you review the returned evidence and chart.

Prepare your project

You need Python 3.12 or newer, an API Project with credits, and a Project API key. A Project administrator configures the connector, skill, and profile. Once you save that configuration, org members can use the analyst profile in their applications. The terminal commands use Bash. On macOS, run bash in each terminal before following them; on Windows, use a Bash terminal in WSL. Choose your data path before starting. The local server is sample infrastructure, not an Agent API requirement. The example uses Brightside Coffee, a fictional subscription business. Its metric counts non-test accounts that signed up and started a paid subscription in the same Monday-to-Sunday week. To reproduce the questions and counts, your connector must serve this sample’s data and context through describe_tables, search_context, and run_sql. For another data source, adapt the tools, skill, instructions, schema, and SQL dialect; the Brightside results will not apply.

Plan the files before creating them

Your application has one file: ask.py. The skill is one folder containing its instructions, SQL reference, and chart helper, packaged together as a ZIP. Add data_server.py only for the local sample; it includes its own data and company context. brightside-analyst contains ask.py and the metric-investigation skill folder, with SKILL.md, references/week-bounds.md, and scripts/plot_weekly.py. Add data_server.py only for the local sample. Create the working folder and install the client library. If you use the downloadable skill ZIP, you can skip creating the skill folder’s contents yourself.

Write your Agent API client

Create ask.py in the working folder and copy the complete file below. It calls Agent API and records what happened; it does not implement the analyst’s investigation.
  • Imports and paths: Load the command-line, JSON, environment, file, and API helpers. RUNS stores responses; LAST_RESPONSE stores the conversation checkpoint.
  • ask(): Call client.responses.create() with a profile and question. Optional arguments select a profile version, override the model, or continue a conversation.
  • show_work(): Save the complete response and print its answer, tool activity, errors, and reported cost. Only completed responses advance the checkpoint.
  • download_files(): Retrieve shared files through the response files endpoints. Use per-response folders, reject path-like names, and refuse overwrites.
  • main() and the entry point: Parse your flags, create the API client, send the request, and handle the response. Reject a follow-up without a valid checkpoint.
If you already have a working Brightside profile, skip configuration and go to Ask your first question. Agent requests use your API credits; the client uses the library’s default retry behavior.

Configure your Agent API analyst

Give the agent a reusable investigation method

Use the metric-investigation skill to tell the agent how to investigate, rather than repeating the method in every question. Its description explains when to load it; its instructions ask the agent to check definitions, compare consistent weeks, investigate tracking changes, and show evidence. Keep the skill as a folder so its instructions, reference, and chart helper travel together. You can download the complete skill ZIP, or create these three files at the paths shown.
SKILL.md contains the investigation sequence and answer format. For charts, it asks the agent to prompt Sandbox with the query results and request the bundled helper.
The supporting reference provides same-calendar-week SQL, a filtered daily query that preserves zero-count days, and a separate billing diagnostic. The skill tells the agent to keep the same metric and cohort in every breakdown.
The chart helper accepts the connector’s JSON results and produces a labeled PNG. It rejects errors and truncated data. The agent requests this helper through a Sandbox prompt, not a direct code-execution call; Sandbox determines what runs. If the helper is unavailable, the skill asks for an equivalent chart from the same query results. The helper belongs to the skill, not your application’s workflow. Package the entire metric-investigation/ folder, not SKILL.md alone:
Open your API Project’s Skills page. Select Create skill, or Update for an existing skill. Drop metric-investigation.zip into the upload area, or click to browse, then select Continue. Update skill dialog for metric-investigation, showing the ZIP upload area and Continue button The screenshot shows updating an existing skill, which creates a new version. Confirm that your upload succeeds, then select that version when you configure the profile.

Connect the agent to your data

Your connector lets Agent API access the data tools without giving your application the server’s credential. If you already have a compatible hosted connector in this Project, select it in the profile below and skip server setup. If you need the synthetic Brightside server, follow Run the sample server locally, then return here with its HTTPS URL and token. Register it on the Project connectors page:
  • Name: brightside-data
  • MCP server URL: Your server’s HTTPS URL plus /mcp
  • Authentication: API Key, using your DATA_SERVER_KEY
  • Transport: Streamable HTTP
Custom connector dialog showing brightside-data, API Key authentication, and Streamable HTTP, with the test endpoint redacted Use your endpoint, not the screenshot’s test host. Confirm that the connector exposes describe_tables, search_context, and run_sql; see the connector reference for Project-scoped credentials.

Save the customizations in a profile

On the Profiles page, create a Custom profile. This is the configuration your application will invoke by ID. Paste the instructions below. They define the analyst’s role and output; the skill supplies its investigation method.
Profile settings with Sandbox under Tools, a pinned metric-investigation Skill, and brightside-data under Connectors Save the profile and copy its ID. Select the skill revision you uploaded; version numbers in your Project can differ from the screenshot. Your client now needs the profile ID and a Perplexity API key from the same Project, not the server token or another copy of the agent’s instructions.

Ask your first question

From the folder containing the ask.py you created above, activate the environment and enter your Project API key at the hidden prompt. Replace the profile placeholder with your saved ID.
The client passes your question as input to client.responses.create(). Agent API uses the saved profile to give the agent its instructions, skill, connector, and tools. You do not write the investigation’s SQL in the application. The sample ends on September 13, 2026, so use explicit dates rather than “last week.” Compare your agent’s output with these known non-test counts: The expected finding is a measurement problem that prevents a confident conclusion about customer behavior. Recorded same-week conversions fall from 110 to 90, while mobile signup records disappear from September 9 through September 12. Non-test billing starts rise from 158 to 170 across the two weeks, so the signup and billing records do not tell the same story. Missing signup records affect both the conversion count and its denominator. A higher observed conversion rate does not prove better purchase performance, and these tables cannot establish the true rate. Billing accounts without a signup in the same week may have signed up earlier; they are not all missing from the signup table. Review the daily diagnostics as well as the headline: each must exclude test accounts. Device, segment, and plan breakdowns must keep the same calendar-week definition. If a required diagnostic fails, the answer should name the missing evidence instead of presenting the investigation as complete. Agent API returns evidence you can inspect, not a guarantee of correct reasoning. ask.py saves the complete response under runs/<response-id>/response.json; check executed queries and their outputs, not only SQL quoted in the answer.

Continue the conversation and get a chart

Next, ask the same agent to focus on enterprise customers. The client sends previous_response_id with your new question so the Agent API request continues the earlier conversation. Keep the profile unchanged during the walkthrough, and run the follow-up from the same working folder.
Your agent can query the enterprise data and prompt Sandbox to create a chart. Sandbox determines what code runs. The client downloads shared files separately through the response files endpoints into runs/<response-id>/files/. Example enterprise chart: signups of 142, 138, 136, and 105, and conversions of 41, 33, 33, and 22 for the four sample weeks The example chart’s eight labels match the synthetic, non-test enterprise counts. The final week includes the tracking gap; these are recorded counts, not reconstructed events. Compare your chart against the successful SQL results before sharing it. Check that your response includes both a downloaded PNG and the JSON used to create it. The chart should have a zero baseline, explicit week dates, a cohort title, and all eight count labels. Include the synthetic-data and September 9 to 12 tracking-gap note with the chart, even if the generated image omits it. If a file or label is missing, request a correction in the same conversation and check the returned files again. Your application sent another question rather than adding a SQL prompt or charting workflow. Keep each conversation in its own working folder, since the client stores one last-completed-response checkpoint per folder.

Reuse the profile from another application

Another application can use the same profile with an API key from the same Project. Pin your tested profile version to keep later configuration edits from changing what that application requests.
The client sets profile.version in the Agent API request. Replace YOUR_TESTED_VERSION with the version you verified; the expected count for this sample is 137. Pinning configuration does not freeze external data or guarantee identical answers. For a pinned conversation, pass the same --version on both the initial request and each follow-up.

Optional: compare a different model

The default model is sufficient for the investigation and chart. To evaluate another model, use --model to set the Agent API request’s model field while retaining the profile. The client supplies the output-token limit used for this Anthropic request. This is an optional evaluation, not a required step or a promise of equivalent analytical quality.
One earlier run returned 35 then 31 conversions instead of 110 then 90. Its SQL required signup and subscription to occur on the same day, not within the same week.
Treat this as a failed analysis. Correct SQL alone is not enough either: reject unsupported claims that the true conversion rate improved, that the business is unaffected, or that every unmatched billing account has no signup record. Profiles let you reuse a configuration across requests; you still need to evaluate each model’s results.

Run the sample server locally

Skip this section if your connector already reaches a hosted server. This supplies test data for the Agent API tutorial; it is not application-side agent orchestration. This path adds just one file, data_server.py, to your working folder. Install its dependency in the environment you created above:

Create the sample data server

Copy the complete code below into data_server.py. This server supplies the connector’s data tools; Agent API still runs the investigation.
  • Sample data: build_rows() creates the same data each time. create_db() loads it into memory and enables SQLite’s query-only mode. No database or context file needs to be created.
  • Company context: CONTEXT holds table descriptions, metric definitions, and the tracking-change note.
  • Connector tools: describe_tables, search_context, and run_sql expose the data. Context search matches every search word; SQL results are capped at 100 rows.
  • Server entry point: RequireKey checks the bearer token. The server requires a token and uses JSON responses over Streamable HTTP.
The sample contains 3,382 accounts, 3,222 signups, and 971 subscriptions. Four days of mobile signup events are deliberately missing while billing records remain.

Make the server reachable

The connector needs a remotely reachable MCP endpoint. This local path uses Cloudflare’s cloudflared tunnel; Agent API does not require Cloudflare. Install it with brew install cloudflared on macOS, or use Cloudflare’s downloads. Use only synthetic data. In terminal 1, activate the environment, enter a random server token at the hidden prompt, and start the server.
Keep it running. In terminal 2, start the tunnel and leave it open too.
In terminal 3, enter the HTTPS URL plus /mcp, then the same server token. Check authentication before registering the connector.
Expect 401 without the token and 200 with it. Return to Connect the agent to your data to register the endpoint and finish configuring the profile. When finished, stop only your local server and tunnel and unset exported token variables. Leave shared hosted services running. Keep credentials and raw responses out of source control.

Troubleshooting

  • Connector unavailable: Check the server, token, URL, and Project. Restarting a quick tunnel changes its URL; replace the connector if you cannot edit that endpoint.
  • No executed SQL: Inspect connector errors and Sandbox results, including nested exit codes. Proposed SQL and a completed status do not prove a successful investigation or helper execution.
  • Wrong counts: Check the non-test filter and same-week boundaries. The server caps returned rows, not query computation.
  • Missing chart: Inspect share_file items and the file download step. A sandbox: path is not a local download. If Sandbox cannot locate the bundled helper, the skill permits an equivalent chart; verify the returned PNG and JSON rather than assuming that helper ran.
  • Incomplete response: Inspect the saved status, error, and incomplete details before raising the step budget.