Add Data Using Nasdaq Metrio™ REST API

The Nasdaq Metrio Public API allows you to programmatically upload data from CSV or XLSX files and JSON format into existing data sources within your Nasdaq Metrio account. This document provides comprehensive information on authentication, endpoints, request formats, and examples to help you integrate your systems seamlessly.

1. Authentication

Before using the Nasdaq Metrio API, you need to generate an API key within your Nasdaq Metrio account.

 

Prerequisites

Ensure that the Nasdaq Metrio REST API feature is activated in your account.

 

 

Key Generation

  1. Click on your profile icon in the top-right corner of the page.
  2. Select API Keys.
  3. Click Generate new key.
  4. Give your key a descriptive name (e.g., "Project X Integration").
  5. Click Generate key.

Important: Copy the generated API key immediately. You will not be able to retrieve it again.

 

 

Key Management

You can create multiple API keys to organize your projects and track usage.
Currently, API keys do not have expiration dates. Please manage your keys securely and regenerate them if you suspect any compromise.

 

 

Security Best Practices

  • Treat your API key like a password. Keep it confidential.
  • Do not embed API keys directly in client-side code (e.g., JavaScript).
  • If you suspect your API key has been compromised, immediately regenerate it.

 

 

2. CSV/XLSX Import

 

This section describes how to import data from CSV or XLSX files into an existing Nasdaq Metrio Data Source using the API.

 

 

Header

 

API endpoints expect arguments as JSON-encoded objects in the POST request body. Set the Content-Type header to application/json.

 

HTTP Header

Content

Content-Type

application/json

X-Metrio-API-Key

<your_api_key>

 

Endpoint

POST https://<customer>.metrio.net/api/datasources/public/v1/datasources/<data_source_key>/imports

 

  • Replace <customer> with the URL prefix of your account (e.g., "demo123" if your account URL is https://demo123.metrio.net).
  • Replace <data_source_key> with the Data Source ID of the target data source (see "Parameter Definition" below).

 

 

Payload details

{
  "delimiter": ",",
  "file": "encoded_file_in_base_64",
  "fileName": "your_file_name.csv",
  "mappings": [
    {
      "index": 0,
      "key": "column_key_in_data_source"
    }
  ],
  "mode": "ignore_duplicates",
  "noteMapping": 1
}

Note: During the import process, the first row of the CSV or XLSX file is automatically ignored, as it is assumed to be a header row. Please ensure your actual data starts on the second row.

 

 

Parameter

Description

Mandatory

Type

delimiter

The delimiter used in the CSV file. Common values are ",", ";", or "\t" (tab). If importing an XLSX file, this parameter is ignored.

No if XLSX

string

file

The content of the CSV or XLSX file, encoded as a Base64 and with a size less than 100 Mb.
 

Yes

string

fileName

The original file name of the CSV or XLSX file (e.g., "data.csv" or "data.xlsx").

Yes

string

mode

  • replace_all: Deletes all existing data in the Data Source and replaces it with the data from the imported file.
  • replace_duplicates: Compares incoming data with existing data based on key attributes. If a match is found (duplicate), the existing row is replaced with the new data. If no match is found, the new row is added. This requires the Data Source to have at least one key attribute.
  • ignore_duplicates: Compares incoming data with existing data based on key attributes. If a match is found (duplicate), the new row is ignored. If no match is found, the new row is added.This requires the Data Source to have at least one key attribute.

Yes

string

mappings

Each object in the mappings array has the following properties:

Yes

array

  • index
The zero-based index of the column in the CSV/XLSX file. The first column is index 0, the second is index 1, and so on.

Yes

integer

  • key
The Attribute ID of the attribute in the Data Source to which the column should be mapped. You can find Attribute IDs in the "Structure" tab of the Data Source in Metrio. 

Yes

string

noteMapping The zero-based index of the column in the CSV/XLSX file that contains the note to be associated with each rows.

No

integer

 

 

File Size Limit

 

The Base64 encoded file string must represent a file that is less than 100 MB in size.

 

 

Response Codes

 

Code

Description

 

201

Created

The import request was successfully submitted.

400

Bad Request

The request was malformed or contained invalid data.

500

Internal Server Error

An unexpected error occurred on the server.

 

 

Request Limits

 

You are limited to 100 submissions every 10 seconds. Exceeding this limit may result in temporary throttling.

 

 

Parameters Definition

 

To use the API to import data in a Data Source, a data source needs to be created (see Create a data source). Once created, to use the API import functionality, the following parameter needs to be defined:

  • <customer> : The URL prefix of your account (e.g., "demo123" if your account URL is https://demo123.metrio.net).
  • <data_source_key>: The Data Source ID of the target Data Source. You can find this value in the "General information" section of the Data Source settings within Nasdaq Metrio. It's labeled "Data source ID".

 

Screenshot 2025-04-07 at 5.50.42 PM.png

 

You can copy the key by hovering the Data Source ID field.

 

 

Example

 

To create an upload file, it is possible to use a template. To download a template, go to the Data Table of the Data Source and click on Import Data.

 

If there is already some previous import in this Data Source, click again on import data. Otherwise, it will redirect you to the import configuration page. There it is possible to download an Excel template.

 

 

The last step is to map your file with the Data Source Attributes keys. Those keys are displayed in the Data Source Structure tab, in the column Attribute ID.

 

 

 

It is also possible to use the Curl example: GET Datasource by Key to the attribute.

 

Limitation: note field uploads are not supported yet by the API. If you already have note content in a data source, and you replace all, you will delete the existing note.

 


 

To try it

 

  • Swagger

You can access and test the API using our Swagger UI:

https://<customer>.metrio.net/api/datasources/public/swagger/index.html
  •  
    • Replace <customer> with your account's URL prefix.
    • You must be logged in to your Nasdaq Metrio account to access the Swagger UI.

 

 

 

  • Python
import base64
import json
import requests
import sys
import time
class bcolors:
   OKGREEN = '\033[92m'
   FAIL = '\033[91m'
   ENDC = '\033[0m'



# Variable to define
customer     = "_YOUR_CLIENT_URL_PREFIX_"         # client URL prefix, ex: demo
key_value      = "_YOUR_API_KEY_"                   # Paste a valid Metrio API key
data_source_key = "_YOUR_DATASOURCE_KEY_"           # The target data source's key
file_name      = "public_api_import_example.xlsx"   # The uploaded file
mode          = "ignore_duplicates"                
# Data creation mode: replace_all, replace_duplicates or ignore_duplicates
noteindex     = 2                                   # The column index for notes, omit if absent.

# Encoding the file in base64
with open(file_name, "rb") as file:
    content = file.read()

encoded_file = base64.b64encode(content).decode("utf-8")

# Mappings of your XLSX/CSV columns to your data sources attribute keys.
# In this case, date and number are the 2 attribute keys and 0 represents
# the first column of your file while 1 represents the second column of your file.
payload = {
    "file": encoded_file,
    "fileName": file_name,
    "mappings": [
        {
        "key": "date",
        "index": 0
        },
        {
        "key": "number",
        "index": 1
        }
    ],
    "mode": mode,
    "noteMapping": noteindex
}

# Adding x-metrio-api-key header value with your valid Metrio API key
headers = {
    "X-Metrio-API-Key": key_value,
    "Content-Type": "application/json"
}


# Building request
url = f"https://{customer}.metrio.net/api/datasources/public/v1/datasources/{data_source_key}/imports"

response = requests.post(url, json=payload, headers=headers)


if response.ok:
    print(response.text)
    print("Importation STARTED")
else:
    response.raise_for_status()
    sys.exit(1)


# Check the import status
import_id = response.json()["id"]
datasource_uuid = response.json()["dataSourceId"]

while True:
    check_import_data = requests.get(f"https://{customer}.metrio.net/api/datasources/public/v1/imports/{import_id}/summary", headers=headers)
    response = check_import_data.json()
    status = response.get("state")
    if status == "success":
        print(f"{bcolors.OKGREEN}Importation FINISH{bcolors.ENDC} - Valid: {bcolors.OKGREEN}{response['reportData']['valid']['total']}{bcolors.ENDC} / Invalid: {bcolors.FAIL}{response['reportData']['invalid']['total']}{bcolors.ENDC} - https://{customer}.metrio.net/data-sources/{datasource_uuid}/data")
        data_imported = response['reportData']['valid']['total']
        break
    elif status == "error":
        print(f"{bcolors.FAIL}Importation FAILED{bcolors.ENDC} {check_import_data.text}")
        sys.exit(1)  # Stop the entire script
    else:
        print("Importation in progress, waiting...")
        time.sleep(5)

 

  • Go
package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"

	"golang.org/x/net/http2"
)

var (
	Customer     = "_YOUR_CLIENT_URL_PREFIX_"       // To replace with production client URL, ex: bonduelle.metrio.net
	KeyValue      = "_YOUR_API_KEY_"                 // Paste a valid Metrio API key
	DataSourceKey = "_YOUR_DATASOURCE_KEY_"          // The target datasource's key, not ID.
	FileName      = "public_api_import_example.xlsx" // The uploaded file
	Mode          = "ignore_duplicates"             
// Data creation mode: replace_all, replace_duplicates or ignore_duplicates
	NoteIndex     = 2                                // The column index for notes, omit if absent.
)

type PublicAPIMappings struct {
	Key   string `json:"key"`
	Index int    `json:"index"`
}

type PublicAPIPayload struct {
	File        string              `json:"file"`
	Mode        string              `json:"mode"`
	FileName    string              `json:"fileName"`
	Mappings    []PublicAPIMappings `json:"mappings"`
	NoteMapping *int                `json:"noteMapping"`
}

func main() {
	url := "https://" + Customer + "api/datasources/public/v1/datasources/" + DataSourceKey + "/imports"
	content, err := os.ReadFile(FileName)
	if err != nil {
		panic(err)
	}

	// Mappings of your xlsx columns to your datasource's attribute keys.
	// In this case, date and number are the 2 attribute keys and 0 represents
	// the first column's index while 1 represents the second column's index.
	mappings := []PublicAPIMappings{
		{
			Key:   "date",
			Index: 0,
		},
		{
			Key:   "number",
			Index: 1,
		},
	}

	// Encoding the file in base64
	encodedFile := base64.StdEncoding.EncodeToString(content)

	// Building the request payload
	payload := PublicAPIPayload{
		File:        encodedFile,
		FileName:    FileName,
		Mode:        Mode,
		Mappings:    mappings,
		NoteMapping: &NoteIndex,
	}

	mPayload, err := json.Marshal(payload)
	if err != nil {
		panic(err)
	}

	// Building request
	request, err := http.NewRequest("POST", url, bytes.NewBuffer(mPayload))
	if err != nil {
		panic(err)
	}

	// Adding x-metrio-api-key header value with your valid Metrio API key
	request.Header.Add("X-Metrio-API-Key", KeyValue)
	request.Header.Add("Content-Type", "application/json")

	// Using http2 to support payloads above 32MB
	client := &http.Client{Transport: &http2.Transport{}}
	response, err := client.Do(request)
	if err != nil {
		panic(err)
	}

	defer response.Body.Close()

	body, err := io.ReadAll(response.Body)
	if err != nil {
		panic(err)
	}

	// Output the response's body in your terminal
	fmt.Print(string(body) + "\n")
}
 

 

 

3. JSON Import with attachments

This section describes how to import data in JSON format and add attachment files to your data.

 

Header

 

API endpoints expect arguments as JSON-encoded objects in the POST request body. Set the Content-Type header to application/json.

 

HTTP Header

Content

Content-Type

application/json

X-Metrio-API-Key

<your_api_key>

 

Endpoint

POST https://<customer>.metrio.net/api/datasources/public/v1/datasources/<data_source_key>/json_imports

 

  • Replace <customer> with the URL prefix of your account (e.g., "demo123" if your account URL is https://demo123.metrio.net).
  • Replace <data_source_key> with the Data Source ID of the target data source. 

 

Payload example

{
  "data": [
    {
      "attributes": {
        "attribute_id_1": "content_1",
        "attribute_id_2": "content_2",
        "attribute_id_3": "content_3"
      },
      "files": [
        {
          "file": "encoded_file_in_base_64",
          "fileName": "your_file_name.csv""
        }
      ],
      "note": "note_for_the_row",
    }
  ],
  "mode": "ignore_duplicates"
}

 

Parameter

Description

Mandatory

Type

data

An array containing the data to be imported. Each object in the array represents a row of data.

Yes

array

data[].attributes

An object containing the attributes for the data row. The keys of this object should correspond to the Attribute IDs of the target Data Source.

Yes

object

data[].files

An array of files to be associated with the data row. Each object in the array has the following properties:

No

array

  • file
The Base64 encoded content of the file

No

string

  • fileName
The name of the file.

No

string

data[].note A note to be associated with the data row.

No

string

mode

  • replace_all: Deletes all existing data in the Data Source and replaces it with the data from the imported file.
  • replace_duplicates: Compares incoming data with existing data based on key attributes. If a match is found (duplicate), the existing row is replaced with the new data. If no match is found, the new row is added. This requires the Data Source to have at least one key attribute.
  • ignore_duplicates: Compares incoming data with existing data based on key attributes. If a match is found (duplicate), the new row is ignored. If no match is found, the new row is added.This requires the Data Source to have at least one key attribute.

Yes

string

 

 

File Size Limit

 

The JSON payload must be less than 100 MB in size.

 

 

Response Codes

 

Code

Description

 

201

Created

The import request was successfully submitted.

400

Bad Request

The request was malformed or contained invalid data.

500

Internal Server Error

An unexpected error occurred on the server.

 

 

 

Example in Python

import base64
import requests
import sys
import time
class bcolors:
    OKGREEN = '\033[92m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'


Customer = "_YOUR_CLIENT_URL_PREFIX_" # client URL prefix, ex: demo 
KeyValue = "_YOUR_API_KEY_"
DataSourceKey = "_YOUR_DATASOURCE_KEY_"

url = "https://"+Customer+".metrio.net/api/datasources/public/v1/datasources/"
+DataSourceKey+"/json_imports"

encoded_file = base64.b64encode("file_content").decode("utf-8")

payload = {
  "data": [
    {
      "attributes": {
        "year": "2021",
        "month": "1",
        "number": "1234"
      },
      "files": [
        {
          "file": encoded_file,
          "fileName": "name_of_your_file"
        }
      ],
      "note": "string"
    }
  ],
  "mode": "ignore_duplicates"
}

headers = {
    "X-Metrio-API-Key": KeyValue,
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)


if response.ok:
    print(response.text)
    print("Importation STARTED")
else:
    response.raise_for_status()
    sys.exit(1)

#Check the import status
import_id = response.json()["id"]
datasource_uuid = response.json()["dataSourceId"]

while True:
    check_import_data = requests.get(f"https://{Customer}.metrio.net/api/datasources/public/v1/imports/{import_id}/summary", headers=headers)
    response = check_import_data.json()
    status = response.get("state")
    if status == "success":
        print(f"{bcolors.OKGREEN}Importation FINISH{bcolors.ENDC} - Valid: {bcolors.OKGREEN}{response['reportData']['valid']['total']}{bcolors.ENDC} / Invalid: {bcolors.FAIL}{response['reportData']['invalid']['total']}{bcolors.ENDC} - https://{Customer}.metrio.net/data-sources/{datasource_uuid}/data")
        data_imported = response['reportData']['valid']['total']
        break
    elif status == "error":
        print(f"{bcolors.FAIL}Importation FAILED{bcolors.ENDC} {check_import_data.text}")
        sys.exit(1)  # Stop the entire script
    else:
        print("Importation in progress, waiting...")
        time.sleep(5)

 

 

4. Other Public Endpoint Available

 

 

Curl example: GET Import by ID

curl https://<customer>.metrio.net/api/datasources/public/v1/imports/<your_import_id> \
  -X Get \ 
  -H 'X-Metrio-API-Key: <copied API key>' \ 
  -H 'Content-Type: application/json'

 

  • Replace <customer> by your url prefix.
  • Replace <your_import_id> by a valid import ID.

 

 

Curl example: GET Import Summary by ID

curl https://<customer>.metrio.net/api/datasources/public/v1/imports/<your_import_id>/summary \
  -X Get \
  -H 'X-Metrio-API-Key: <copied API key>' \
  -H 'Content-Type: application/json'

 

  • Replace <customer> by your url prefix.
  • Replace <your_import_id> by a valid import ID and adjust items_per_bucket or omit it if needed.

 

 

Curl example: GET Datasource by Key

curl https://<customer>.metrio.net/api/datasources/public/v1/datasources/<your_datasource_key> \
  -X Get \ 
  -H 'X-Metrio-API-Key: <copied API key>' \ 
  -H 'Content-Type: application/json'

 

  • Replace <customer> by your url prefix.
  • Replace <your_datasource_key> by a valid datasource key.

 

 

Was this article helpful?
0 out of 0 found this helpful