Load Mercado Ads data to DuckDB
Build a Mercado Ads to DuckDB pipeline with your coding agent. One prompt scaffolds it with the dltHub AI harness, plus the Mercado Ads API base URL, auth, endpoints, and incremental loading.
Mercado Ads is an advertising API from Mercado Libre that provides campaign, ad, and metrics endpoints for managing and reporting on sponsored product ads. Everything needed to build a working Mercado Ads → DuckDB pipeline is on this page: the API's base URL, authentication, endpoints, pagination and incremental field — plus a prompt that hands the whole job to your coding agent.
Build your Mercado Ads to DuckDB pipeline
Paste this prompt into Claude, Codex, or Cursor. The agent does the rest.
PromptRunuvx dlthub-init@latestto build a pipeline from Mercado Ads to DuckDB and run it on dltHub
That scaffolds a dltHub workspace and installs the dltHub AI harness — the project rules, the secrets-management skill, and the dlt MCP server your agent needs to work safely. From there it reads the Mercado Ads API, proposes the endpoints to load, then writes, runs and validates the pipeline while you review rather than type. Credentials are inspected through MCP tools, so your agent never reads secrets.toml itself. How the LLM-native workflow works →
Prefer to write it yourself? Every fact the agent uses is below.
Mercado Ads API at a glance
| Base URL | https://api.mercadolibre.com |
| Example endpoint | GET advertising/advertisers/{advertiser_id}/product_ads/campaigns/search |
| Records found at | results |
| Authentication | all requests require a Bearer token in the Authorization header — sent in the Authorization header, prefixed Bearer |
| Pagination | Offset-based page size via limit (default 50). The API uses offset-based pagination with limit and offset query parameters. The response contains a paging object (with total, offset, and limit). Some endpoints may also return a last_item_id. |
| API reference | https://developers.mercadolibre.com.ar/en_us/en_us/product-ads-us-read |
These values come from the Mercado Ads API reference — the authoritative source if anything here looks out of date.
How do I authenticate with the Mercado Ads API?
Requests must include an Authorization header with a Bearer access token, typically in the format 'Bearer APP_USR-...'. Some endpoints also require an 'Api-Version' header.
1. Get your credentials
- Sign in to the Mercado Libre Developers portal and navigate to your application dashboard (My Apps). 2. Create a new application if one does not exist, or select an existing one. 3. Note your client_id and client_secret from the application overview. 4. Configure the required Redirect URI and ensure the advertising/Product Ads (advertising/product_ads) scope is enabled for your app. 5. Initiate the OAuth 2.0 authorization code flow by redirecting users to the Mercado Libre authorization URL, then perform a POST request to the token endpoint to exchange the authorization code for an access_token.
2. Add them to .dlt/secrets.toml
[sources.mercado_ads_source] client_id = "your_client_id" client_secret = "your_client_secret" access_token = "your_access_token"
dlt reads this file automatically at runtime. With the harness, the setup-secrets skill prompts you for the values and never handles the raw credential in chat. For production, see setting up credentials with dlt.
What Mercado Ads data can I load into DuckDB?
These are the Mercado Ads endpoints dlt can load into DuckDB:
| Resource | Endpoint | Method | Data selector | Description |
|---|---|---|---|---|
| product_campaigns_search | advertising/advertisers/{advertiser_id}/product_ads/campaigns/search | GET | results | List/search campaigns |
| product_ads_search | advertising/advertisers/{advertiser_id}/product_ads/ads/search | GET | results | List/search ads |
| product_items_metrics | advertising/advertisers/{advertiser_id}/product_ads/items | GET | results | Item-level metrics |
| brand_campaigns | advertising/advertisers/{advertiser_id}/brand_ads/campaigns | GET | List brand ad campaigns | |
| display_campaigns | advertising/advertisers/{advertiser_id}/display/campaigns | GET | List display campaigns |
How do I load only new Mercado Ads records?
The Mercado Ads API reference does not document a timestamp or sequence field for these endpoints, so there is nothing to advertise here as verified. Pick a field from the endpoints table above that increases with every write, then set it as the cursor_path.
{"name": "product_campaigns_search", "endpoint": { "path": "advertising/advertisers/{advertiser_id}/product_ads/campaigns/search", # Replace with a field that increases on every write. "incremental": {"cursor_path": "REPLACE_ME", "initial_value": "2024-01-01T00:00:00Z"}, }}
On the first run dlt loads everything from initial_value; on every run after that it requests only what changed and appends with write_disposition="merge" if you set a primary key. See incremental loading.
What does the generated Mercado Ads pipeline look like?
A standard dlt REST API pipeline — the same code you would write by hand, loading /advertising/advertisers and /advertising/product_ads/items from the Mercado Ads API into DuckDB:
import dlt from dlt.sources.rest_api import RESTAPIConfig, rest_api_resources @dlt.source def mercado_ads_source(access_token=dlt.secrets.value): config: RESTAPIConfig = { "client": { "base_url": "https://api.mercadolibre.com", "auth": {"type": "bearer", "token": access_token}, }, "resources": [ {"name": "product_campaigns_search", "endpoint": {"path": "advertising/advertisers/{advertiser_id}/product_ads/campaigns/search", "data_selector": "results"}}, {"name": "product_ads_search", "endpoint": {"path": "advertising/advertisers/{advertiser_id}/product_ads/ads/search", "data_selector": "results"}} ], } yield from rest_api_resources(config) def load_mercado_ads_to_duckdb() -> None: pipeline = dlt.pipeline( pipeline_name="mercado_ads_pipeline", destination="duckdb", dataset_name="mercado_ads_data", ) load_info = pipeline.run(mercado_ads_source()) print(load_info) if __name__ == "__main__": load_mercado_ads_to_duckdb()
Run it with python mercado_ads_pipeline.py. The agent iterates on this until it loads cleanly — you review and approve, rather than write it from scratch.
How do I query Mercado Ads data in DuckDB?
dlt creates one table per resource. Query the loaded data with Python or SQL — or ask your agent to, through the MCP server's execute_sql_query tool.
Python (pandas DataFrame):
import dlt data = dlt.pipeline("mercado_ads_pipeline").dataset() df = data.product_campaigns_search.df() print(df.head())
SQL:
SELECT * FROM mercado_ads_data.product_campaigns_search LIMIT 10;
See querying your data with dataset and exploring it in marimo notebooks.
How do I deploy the Mercado Ads to DuckDB pipeline in production?
The pipeline runs locally, which is ideal for prototyping and one-off analysis. When you need it on a schedule, monitored on every load, and shared with your team, deploy the same dlt code on the dltHub platform — no infrastructure to maintain. The prompt above already ends with "run it on dltHub", so your agent can take it there directly.
- Deploy & schedule — run the pipeline as a managed job with automatic retries.
- Monitor — observable job queues, alerting, and load metrics for every run.
- Transform — promote raw Mercado Ads loads into governed, documented models.
- Visualize & share — explore data in notebooks and publish live dashboards instead of static screenshots.
What other destinations can I load Mercado Ads data to?
dlt loads into any of these — only the destination argument changes:
| Destination | Example value |
|---|---|
| PostgreSQL | "postgres" |
| BigQuery | "bigquery" |
| Snowflake | "snowflake" |
| Redshift | "redshift" |
| Databricks | "databricks" |
| Filesystem (S3, GCS, Azure) | "filesystem" |
Set dlt.pipeline(destination="snowflake") and add credentials in .dlt/secrets.toml. On the dltHub platform the same pipeline runs against a managed Iceberg lakehouse. See the full destinations list.
Next steps
Was this page helpful?
Community Hub
Need more dlt context for Mercado Ads to DuckDB?
Request dlt skills, commands, AGENT.md files, and AI-native context.