Skip to main content
Import your data into Tako using the Tako Connect API to unlock AI-powered analysis and visualization capabilities.

Connect Your Data

Tako supports two methods for bringing your data:
  1. Upload a local file
  2. Connect to a hosted file via URL
Follow the guide below to upload or connect your data with Tako

Upload Local Files via API

First, generate a presigned url using the GET /file_upload_url endpoint. Then you can POST your file to the url

Step 1: Request Upload URL

Request
curl --request GET \
  --url 'https://trytako.com/api/v1/beta/file_upload_url?file_name=<your_file_name>' \
  --header 'content-type: application/json' \
  --header 'x-api-key: <your_api_key>'

Sample Response

Response
{
  "url": "https://tako-byod-files-production.s3.amazonaws.com/",
  "fields": {
    "Content-Type": "text/csv",
    "key": "byod/10a2b16e-7116-4023-9f0e-d61f99cedd89/<your_file_name>",
    "x-amz-algorithm": "",
    "x-amz-credential": "",
    "x-amz-date": "",
    "policy": "",
    "x-amz-signature": ""
  },
  "key": "byod/10a2b16e-7116-4023-9f0e-d61f99cedd89/<your_file_name>"
}

Step 2: Upload Your File

Use the url and fields from the response to upload your file using a multipart/form-data request.
Upload File
curl -X POST "https://tako-byod-files-production.s3.amazonaws.com/" \
  -F "Content-Type=text/csv" \
  -F "key=byod/10a2b16e-7116-4023-9f0e-d61f99cedd89/<your_file_name>" \
  -F "x-amz-algorithm=" \
  -F "x-amz-credential=" \
  -F "x-amz-date=" \
  -F "policy=" \
  -F "x-amz-signature=" \
  -F "file=@/path/to/your/local/file"

Connect External Files via URL

If your data is hosted elsewhere (e.g., S3, Dropbox, Google Drive), you can register it with Tako using the POST /file_connector endpoint.
File Connector
curl --request POST \
  --url https://trytako.com/api/v1/beta/file_connector \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <api-key>' \
  --data '{
  "file_id": "<string>",
  "file_url": "<string>"
}'
If the original file is updated, call the file_connector endpoint again with the same file_id and updated file_url to propagate changes to Tako.

Query Tako with Your Data

Once your file is uploaded or connected, use the POST /visualize endpoint to generate insights and visualizations. In the body, include the file_id from the response of /file_upload_url or /file_connector. Optionally, include a natural language query.
Query: Timeseries graph comparing Tokyo Balls’ and Tako Bell’s monthly revenue (total + tip)

Zero Data Retention (ZDR) Embeds

Zero Data Retention lets you render charts without persisting your data on Tako servers. You send the visualization payload at render time, either via our lightweight widget or by posting directly to the embed endpoint.

How it works

  • You generate a card via the visualize API as usual and receive a card_id and a visualization_data object.
  • To render: you either
    • use the TakoZDREmbed widget to create an iframe and POST the visualization_data for you, or
    • POST the visualization_data directly to the embed URL with an HTML <form> that targets an <iframe>.
  • Data is not stored by Tako; it exists only in your request and the user’s browser.

Option A: Use the ZDR Embed widget

  1. Include the widget in your app (serve the file from your app or a CDN):
<script src="zdr_embed_widget.js"></script>
  1. Create a container where the chart will render:
<div id="my-zdr-chart"></div>
  1. Render using your card_id and visualization_data:
const chart = window.TakoZDREmbed.render({
  containerId: "my-zdr-chart",
  takoUrl: "https://trytako.com", // or your self-hosted Tako URL
  cardId: "YOUR_CARD_ID",
  visualizationData: {
    viz_config: { /* chart config */ },
    data: { /* chart data */ }
  },
  width: "100%",
  height: "600px"
});
/**
 * Tako ZDR Chart Embed Widget
 *
 * A standalone JavaScript snippet for embedding Tako charts with Zero Data Retention (ZDR).
 * This widget allows you to embed charts without storing sensitive data on Tako's servers.
 *
 * Usage:
 *
 * <div id="my-chart"></div>
 * <script>
 *   TakoZDREmbed.render({
 *     containerId: 'my-chart',
 *     takoUrl: 'https://trytako.com',
 *     cardId: 'ABC123xyz',
 *     visualizationData: {
 *       viz_config: { ... },
 *       data: { ... }
 *     }
 *   });
 * </script>
 */

(function (window) {
  "use strict";

  const TakoZDREmbed = {
    /**
     * Render a ZDR chart embed
     *
     * @param {Object} options - Configuration options
     * @param {string} options.containerId - DOM element ID where the chart will be embedded
     * @param {string} options.takoUrl - Base URL of your Tako instance (e.g., 'https://trytako.com')
     * @param {string} options.cardId - The chart card ID returned from the visualize API
     * @param {Object} options.visualizationData - The visualization_data object containing viz_config and data
     * @param {Object} options.visualizationData.viz_config - The chart configuration
     * @param {Object} options.visualizationData.data - The chart data
     * @param {number} [options.width] - Width of the iframe (default: '100%')
     * @param {number} [options.height] - Height of the iframe (default: '600px')
     * @param {Function} [options.onLoad] - Callback function called when chart loads
     * @param {Function} [options.onError] - Callback function called if there's an error
     *
     * @returns {Object} - Object with iframe element and destroy method
     */
    render: function (options) {
      // Validate required options
      if (!options.containerId) {
        throw new Error("TakoZDREmbed: containerId is required");
      }
      if (!options.takoUrl) {
        throw new Error("TakoZDREmbed: takoUrl is required");
      }
      if (!options.cardId) {
        throw new Error("TakoZDREmbed: cardId is required");
      }
      if (!options.visualizationData) {
        throw new Error("TakoZDREmbed: visualizationData is required");
      }
      if (!options.visualizationData.viz_config) {
        throw new Error(
          "TakoZDREmbed: visualizationData.viz_config is required"
        );
      }
      if (!options.visualizationData.data) {
        throw new Error("TakoZDREmbed: visualizationData.data is required");
      }

      // Get container element
      const container = document.getElementById(options.containerId);
      if (!container) {
        throw new Error(
          "TakoZDREmbed: Container element not found: " + options.containerId
        );
      }

      // Set default dimensions
      const width = options.width || "100%";
      const height = options.height || "600px";

      // Create embed URL
      const embedUrl =
        options.takoUrl.replace(/\/$/, "") + "/embed/" + options.cardId + "/";

      // Create iframe
      const iframeName = "tako-zdr-embed-" + options.cardId + "-" + Date.now();
      const iframe = document.createElement("iframe");
      iframe.name = iframeName;
      iframe.id = iframeName;
      iframe.style.width = width;
      iframe.style.height = height;
      iframe.style.border = "none";
      iframe.setAttribute("scrolling", "no");
      iframe.setAttribute("frameborder", "0");

      // Add load handler
      if (options.onLoad) {
        iframe.addEventListener("load", function () {
          options.onLoad(iframe);
        });
      }

      // Add iframe to container
      container.innerHTML = "";
      container.appendChild(iframe);

      // Create and submit form to iframe
      try {
        const form = document.createElement("form");
        form.method = "POST";
        form.action = embedUrl;
        form.target = iframeName;
        form.style.display = "none";

        // Create hidden input with visualization_data
        const input = document.createElement("input");
        input.type = "hidden";
        input.name = "visualization_data";
        input.value = JSON.stringify(options.visualizationData);

        form.appendChild(input);
        document.body.appendChild(form);

        // Submit form
        form.submit();

        // Clean up form after a short delay
        setTimeout(function () {
          if (form.parentNode) {
            document.body.removeChild(form);
          }
        }, 100);
      } catch (error) {
        if (options.onError) {
          options.onError(error);
        } else {
          console.error("TakoZDREmbed: Error creating embed:", error);
        }
      }

      // Return object with iframe reference and destroy method
      return {
        iframe: iframe,
        destroy: function () {
          if (iframe.parentNode) {
            iframe.parentNode.removeChild(iframe);
          }
        },
        update: function (newVisualizationData) {
          // Re-render with new data
          TakoZDREmbed.render({
            containerId: options.containerId,
            takoUrl: options.takoUrl,
            cardId: options.cardId,
            visualizationData: newVisualizationData,
            width: width,
            height: height,
            onLoad: options.onLoad,
            onError: options.onError,
          });
        },
      };
    },

    /**
     * Render multiple charts at once
     *
     * @param {Array} charts - Array of chart configuration objects
     * @returns {Array} - Array of chart instances
     */
    renderMultiple: function (charts) {
      return charts.map(function (chartConfig) {
        return TakoZDREmbed.render(chartConfig);
      });
    },
  };

  // Expose to global scope
  window.TakoZDREmbed = TakoZDREmbed;
})(window);

Option B: Direct POST to the embed (no widget)

Use a hidden <form> that posts your visualization_data JSON to the embed endpoint, targeting an <iframe>.
<!-- Replace EMBED_URL_GOES_HERE with your embed URL: e.g. https://trytako.com/embed/<CARD_ID>/ -->
<div style="margin: 16px 0;">
  <button id="zdr-render-btn">Render ZDR Embed</button>
</div>

<iframe
  name="zdr-embed-frame"
  id="zdr-embed-frame"
  style="width: 100%; height: 600px; border: none;"
></iframe>

<form
  id="zdr-embed-form"
  method="POST"
  action="EMBED_URL_GOES_HERE"
  target="zdr-embed-frame"
  style="display: none;"
>
  <input
    type="hidden"
    name="visualization_data"
    id="zdr-visualization-data"
    value='{}'
  />
</form>

<script>
  // Paste your visualization_data JSON in the object below
  const zdrVisualizationData = {
    // viz_config: { /* chart config */ },
    // data: { /* chart data */ }
  };

  document.getElementById('zdr-render-btn').addEventListener('click', function () {
    // Set the JSON blob
    document.getElementById('zdr-visualization-data').value = JSON.stringify(zdrVisualizationData);
    // Submit to render in the iframe
    document.getElementById('zdr-embed-form').submit();
  });
</script>

End-to-end flow

  1. Call POST /v1/beta/visualize with your data and query.
  2. Extract card_id and visualization_data from the response.
  3. Render with either the widget or direct form-post approach shown above.