Documentation Index
Fetch the complete documentation index at: https://developer.noodle.cx/llms.txt
Use this file to discover all available pages before exploring further.
Este guia descreve o processo de autenticação para interagir com a Noodle External API, que utiliza chaves assimétricas e JSON Web Tokens (JWT) com o algoritmo ES256 para segurança.
Visão Geral da Autenticação
O processo de autenticação envolve os seguintes passos principais:
- Geração de Chaves Assimétricas: Você precisará de um par de chaves pública e privada. A chave privada é usada para assinar suas requisições e deve ser mantida em segredo. A chave pública é usada pelo servidor para verificar a assinatura.
- Geração do Hash do Corpo da Requisição: Um hash MD5 do corpo da sua requisição (se houver) é gerado.
- Criação do JWT: Um JWT é criado contendo informações da requisição (método, URL, hash do corpo), timestamp, seu ID de usuário e chave de API. Este JWT é assinado com sua chave privada usando o algoritmo ES256.
- Envio da Requisição: O JWT assinado é enviado no cabeçalho
Authorization da sua requisição HTTP.
1) Geração de Chaves Assimétricas (ES256 - secp256r1)
Use os seguintes comandos Unix (OpenSSL) para gerar suas chaves. Guarde sua chave privada (private_key.pem) em um ambiente seguro e nunca a compartilhe.
Gerar Chave Privada:
openssl ecparam -name secp256r1 -genkey -noout -out private_key.pem
Gerar Chave Pública a partir da Chave Privada:
openssl ec -in private_key.pem -pubout -out public_key.pem
2. Geração do Token de Autenticação (JWT)
O token de autenticação é um JWT assinado com sua chave privada. Os seguintes campos são necessários no payload do JWT:
| Campo | Descrição | Exemplo (do Documento) |
payload_md5 | Hash MD5 do corpo da requisição JSON. | md5(json.dumps(request_body).encode()).hexdigest() |
timestamp | Timestamp atual no formato UTC: %Y-%m-%dT%H:%M:%S.%fZ (ex: 2023-10-26T10:00:00.000Z). | datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ") |
method | Método HTTP da requisição (ex: “POST”, “GET”). | "POST" |
url | A URL do endpoint da API que está sendo chamada (sem o domínio base, apenas o caminho). Ex: /external. | "https://prodcution.api.noodle.cx/external/split" |
user_id | Seu ID de usuário fornecido. | "adc936da-1c92-11ef-8696-e2e1e3dec240" |
api_key | Sua chave de API fornecida. | "b860df30-8d03-34ed-0436-02081e3dec48" |
O cabeçalho do JWT (JOSE header) deve ser:
{
"typ": "JWT",
"alg": "ES256"
}
3. Exemplos de Código para Gerar o Cabeçalho de Autenticação
Abaixo estão exemplos de como gerar o JWT e o cabeçalho de autorização em diferentes linguagens de programação. Você precisará adaptar o carregamento da chave privada e a estrutura exata da sua requisição.
Python
JavaScript
Java
C#
Go
PHP
Ruby
Dart
Python
Este exemplo é baseado diretamente no documento fornecido.import json
from datetime import datetime, timezone
from hashlib import md5
from jose import jwt, exceptions as jose_exceptions
from typing import Dict
BASE_URL = "[https://homolog.api.noodle.cx](https://homolog.api.noodle.cx)"
USER_ID = "82f04bce-e088-11ee-acd2-299d225f5178"
API_KEY = "fdef711f-8c6b-476d-b1cf-c9c340422763"
PRIVATE_KEY_PEM = """-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49
AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq
C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==
-----END EC PRIVATE KEY-----"""
def generate_auth_header(method: str, url: str, body_dict: Dict) -> Dict:
"""
a url aqui é a URL completa do endpoint, incluindo o domínio base.
"""
try:
json_body_str = json.dumps(body_dict, separators=(',', ':'))
body_md5_hash = md5(json_body_str.encode('utf-8')).hexdigest()
timestamp_now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
jwt_payload = {
"payload_md5": body_md5_hash,
"timestamp": timestamp_now,
"method": method,
"url": url,
"user_id": USER_ID,
"api_key": API_KEY
}
encoded_token = jwt.encode(
claims=jwt_payload,
key=PRIVATE_KEY_PEM,
algorithm="ES256",
headers={"typ": "JWT", "alg": "ES256"}
)
print("✅ Token JWT gerado com sucesso!")
return {"Authorization": encoded_token}
except jose_exceptions.JOSEError as e:
print(f"❌ Erro ao gerar o token JWT: {e}")
raise
JavaScript (Node.js)
Você precisará de bibliotecas como jsonwebtoken e crypto. Instale com npm install jsonwebtoken crypto.const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const USER_ID = "82f04bce-e088-11ee-acd2-299d225f5178";
const API_KEY = "fdef711f-8c6b-476d-b1cf-c9c340422763";
const PRIVATE_KEY_PEM = `-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49
AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq
C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==
-----END EC PRIVATE KEY-----`;
function generateAuthHeader(method, url, bodyDict) {
/**
* a url aqui é a URL completa do endpoint, incluindo o domínio base.
*/
try {
const jsonBodyStr = JSON.stringify(bodyDict); // Compact by default
const bodyMd5Hash = crypto.createHash('md5').update(jsonBodyStr, 'utf-8').digest('hex');
const timestampNow = new Date().toISOString(); // YYYY-MM-DDTHH:mm:ss.sssZ
const jwtPayload = {
payload_md5: bodyMd5Hash,
timestamp: timestampNow,
method: method,
url: url,
user_id: USER_ID,
api_key: API_KEY
};
const encodedToken = jwt.sign(
jwtPayload,
PRIVATE_KEY_PEM,
{ algorithm: "ES256", header: { typ: "JWT", alg: "ES256" } }
);
console.log("✅ Token JWT gerado com sucesso!");
return { "Authorization": encodedToken };
} catch (error) {
console.error(`❌ Erro ao gerar o token JWT: ${error}`);
throw error;
}
}
Java
Bibliotecas como com.auth0:java-jwt, com.fasterxml.jackson.core:jackson-databind e BouncyCastle.Maven:<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.Security;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
public class NoodleAuthJava {
static { Security.addProvider(new BouncyCastleProvider()); }
private static final String USER_ID = "82f04bce-e088-11ee-acd2-299d225f5178";
private static final String API_KEY = "fdef711f-8c6b-476d-b1cf-c9c340422763";
private static final String PRIVATE_KEY_PEM = "-----BEGIN EC PRIVATE KEY-----\n" +
"MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49\n" +
"AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq\n" +
"C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==\n" +
"-----END EC PRIVATE KEY-----";
private static final ObjectMapper objectMapper = new ObjectMapper();
public static Map<String, String> generateAuthHeader(String method, String url, Map<String, Object> bodyDict) throws Exception {
try {
String jsonBodyStr = objectMapper.writeValueAsString(bodyDict);
String bodyMd5Hash = getMd5Hash(jsonBodyStr);
String timestampNow = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.withZone(ZoneOffset.UTC)
.format(Instant.now());
ECPrivateKey ecPrivateKey = loadPrivateKeyFromPem(PRIVATE_KEY_PEM);
Algorithm algorithm = Algorithm.ECDSA256(null, ecPrivateKey);
Map<String, Object> joseHeader = new HashMap<>();
joseHeader.put("typ", "JWT");
joseHeader.put("alg", "ES256");
String encodedToken = JWT.create()
.withHeader(joseHeader)
.withClaim("payload_md5", bodyMd5Hash)
.withClaim("timestamp", timestampNow)
.withClaim("method", method)
.withClaim("url", url)
.withClaim("user_id", USER_ID)
.withClaim("api_key", API_KEY)
.sign(algorithm);
System.out.println("✅ Token JWT gerado com sucesso!");
Map<String, String> authHeader = new HashMap<>();
authHeader.put("Authorization", encodedToken);
return authHeader;
} catch (Exception e) {
System.err.println("❌ Erro ao gerar o token JWT: " + e.getMessage());
throw e;
}
}
private static String getMd5Hash(String input) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) { sb.append(String.format("%02x", b)); }
return sb.toString();
}
private static ECPrivateKey loadPrivateKeyFromPem(String pemKey) throws Exception {
PemReader pemReader = new PemReader(new StringReader(pemKey));
PemObject pemObject = pemReader.readPemObject();
pemReader.close();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemObject.getContent());
KeyFactory kf = KeyFactory.getInstance("EC", "BC");
return (ECPrivateKey) kf.generatePrivate(keySpec);
}
}
C# (.NET)
Use System.IdentityModel.Tokens.Jwt. Adicione o NuGet System.IdentityModel.Tokens.Jwt.using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using Microsoft.IdentityModel.Tokens;
public class NoodleAuthCSharp {
private const string UserId = "82f04bce-e088-11ee-acd2-299d225f5178";
private const string ApiKey = "fdef711f-8c6b-476d-b1cf-c9c340422763";
private const string PrivateKeyPem = @"-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49
AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq
C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==
-----END EC PRIVATE KEY-----";
public static Dictionary<string, string> GenerateAuthHeader(string method, string url, Dictionary<string, object> bodyDict) {
try {
var jsonOptions = new JsonSerializerOptions { WriteIndented = false };
string jsonBodyStr = JsonSerializer.Serialize(bodyDict, jsonOptions);
string bodyMd5Hash = GetMd5Hash(jsonBodyStr);
string timestampNow = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
ECDsa ecdsaPrivateKey = LoadPrivateKeyFromPem(PrivateKeyPem);
var securityKey = new ECDsaSecurityKey(ecdsaPrivateKey);
var jwtHeader = new JwtHeader(new SigningCredentials(securityKey, SecurityAlgorithms.EcdsaSha256));
jwtHeader["typ"] = "JWT";
var claims = new[] {
new Claim("payload_md5", bodyMd5Hash),
new Claim("timestamp", timestampNow),
new Claim("method", method),
new Claim("url", url),
new Claim("user_id", UserId),
new Claim("api_key", ApiKey)
};
var payload = new JwtPayload(claims);
var tokenHandler = new JwtSecurityTokenHandler();
var token = new JwtSecurityToken(jwtHeader, payload);
string encodedToken = tokenHandler.WriteToken(token);
Console.WriteLine("✅ Token JWT gerado com sucesso!");
return new Dictionary<string, string> { { "Authorization", encodedToken } };
} catch (Exception e) {
Console.Error.WriteLine($"❌ Erro ao gerar o token JWT: {e.Message}");
throw;
}
}
private static string GetMd5Hash(string input) {
using (MD5 md5 = MD5.Create()) {
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
var sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++) { sb.Append(hashBytes[i].ToString("x2")); }
return sb.ToString();
}
}
private static ECDsa LoadPrivateKeyFromPem(string pem) {
var base64 = pem.Replace("-----BEGIN EC PRIVATE KEY-----", "")
.Replace("-----END EC PRIVATE KEY-----", "")
.Replace("\n", "").Replace("\r", "").Trim();
var keyBytes = Convert.FromBase64String(base64);
var ecdsa = ECDsa.Create();
ecdsa.ImportECPrivateKey(keyBytes, out _);
return ecdsa;
}
}
Go (Golang)
Use a biblioteca github.com/golang-jwt/jwt/v5.package main
import (
"crypto/ecdsa"
"crypto/md5"
"crypto/x509"
"encoding/hex"
"encoding/json"
"encoding/pem"
"fmt"
"log"
"time"
"github.com/golang-jwt/jwt/v5"
)
const (
userID = "82f04bce-e088-11ee-acd2-299d225f5178"
apiKey = "fdef711f-8c6b-476d-b1cf-c9c340422763"
privateKeyPEM = `-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49
AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq
C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==
-----END EC PRIVATE KEY-----`
)
func generateAuthHeader(method string, url string, bodyDict map[string]interface{}) (map[string]string, error) {
jsonBodyBytes, err := json.Marshal(bodyDict)
if err != nil {
return nil, fmt.Errorf("❌ erro ao serializar JSON: %w", err)
}
hasher := md5.New()
hasher.Write(jsonBodyBytes)
bodyMD5Hash := hex.EncodeToString(hasher.Sum(nil))
timestampNow := time.Now().UTC().Format("2006-01-02T15:04:05.000Z")
ecPrivateKey, err := loadECPrivateKeyFromPEMString(privateKeyPEM)
if err != nil {
return nil, fmt.Errorf("❌ erro ao carregar chave privada: %w", err)
}
claims := jwt.MapClaims{
"payload_md5": bodyMD5Hash,
"timestamp": timestampNow,
"method": method,
"url": url,
"user_id": userID,
"api_key": apiKey,
}
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
token.Header["typ"] = "JWT"
encodedToken, err := token.SignedString(ecPrivateKey)
if err != nil {
return nil, fmt.Errorf("❌ erro ao assinar token: %w", err)
}
log.Println("✅ Token JWT gerado com sucesso!")
return map[string]string{"Authorization": encodedToken}, nil
}
func loadECPrivateKeyFromPEMString(pemString string) (*ecdsa.PrivateKey, error) {
block, _ := pem.Decode([]byte(pemString))
if block == nil {
return nil, fmt.Errorf("falha ao decodificar o bloco PEM")
}
privateKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
return nil, fmt.Errorf("falha ao analisar a chave privada EC: %w", err)
}
return privateKey, nil
}
PHP
Use a biblioteca firebase/php-jwt. Instale com composer require firebase/php-jwt.<?php
require_once('vendor/autoload.php');
use \Firebase\JWT\JWT;
const USER_ID = "82f04bce-e088-11ee-acd2-299d225f5178";
const API_KEY = "fdef711f-8c6b-476d-b1cf-c9c340422763";
const PRIVATE_KEY_PEM = <<<EOD
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49
AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq
C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==
-----END EC PRIVATE KEY-----
EOD;
function generateAuthHeader(string $method, string $url, array $bodyDict): array
{
try {
$jsonBodyStr = json_encode($bodyDict, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$bodyMd5Hash = md5($jsonBodyStr);
$timestampNow = (new DateTime('now', new DateTimeZone('UTC')))->format('Y-m-d\TH:i:s.v\Z');
$jwtPayload = [
"payload_md5" => $bodyMd5Hash,
"timestamp" => $timestampNow,
"method" => $method,
"url" => $url,
"user_id" => USER_ID,
"api_key" => API_KEY
];
$headers = ["typ" => "JWT", "alg" => "ES256"];
$encodedToken = JWT::encode($jwtPayload, PRIVATE_KEY_PEM, 'ES256', null, $headers);
echo "✅ Token JWT gerado com sucesso!\n";
return ["Authorization" => $encodedToken];
} catch (Exception $e) {
echo "❌ Erro ao gerar o token JWT: " . $e->getMessage() . "\n";
throw $e;
}
}
?>
Ruby
Use a biblioteca jwt. Instale com gem install jwt.require 'jwt'
require 'digest'
require 'json'
require 'time'
USER_ID = "82f04bce-e088-11ee-acd2-299d225f5178"
API_KEY = "fdef711f-8c6b-476d-b1cf-c9c340422763"
PRIVATE_KEY_PEM = <<~PEM
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49
AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq
C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==
-----END EC PRIVATE KEY-----
PEM
def generate_auth_header(method, url, body_dict)
begin
json_body_str = body_dict.to_json
body_md5_hash = Digest::MD5.hexdigest(json_body_str)
timestamp_now = Time.now.utc.iso8601(3)
jwt_payload = {
payload_md5: body_md5_hash,
timestamp: timestamp_now,
method: method,
url: url,
user_id: USER_ID,
api_key: API_KEY
}
headers = { typ: 'JWT', alg: 'ES256' }
ecdsa_key = OpenSSL::PKey::EC.new(PRIVATE_KEY_PEM)
encoded_token = JWT.encode(jwt_payload, ecdsa_key, 'ES256', headers)
puts "✅ Token JWT gerado com sucesso!"
{ "Authorization" => encoded_token }
rescue => e
puts "❌ Erro ao gerar o token JWT: #{e.message}"
raise
end
end
Dart
Use as bibliotecas dart_jsonwebtoken e crypto. Adicione ao seu pubspec.yaml:dependencies:
dart_jsonwebtoken: ^2.12.0
crypto: ^3.0.3
import 'dart:convert';
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:crypto/crypto.dart';
const userId = "82f04bce-e088-11ee-acd2-299d225f5178";
const apiKey = "fdef711f-8c6b-476d-b1cf-c9c340422763";
const privateKeyPem = """-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIO8Bh+h4TkpoA1yVa0V1lX85UeAnXd2bmgFs9k67X4UKoAoGCCqGSM49
AwEHoUQDQgAE2hsBhwR3Od4CgBnT/DVZH+SBsyn74IMABdmcjYZOJIbVySYYSQGq
C5jvT8zoE5GDlQEHX0j7vKGrZO4YXnwlxQ==
-----END EC PRIVATE KEY-----""";
Map<String, String> generateAuthHeader(String method, String url, Map<String, dynamic> bodyDict) {
try {
final jsonBodyStr = json.encode(bodyDict);
final bodyMd5Hash = md5.convert(utf8.encode(jsonBodyStr)).toString();
final timestampNow = DateTime.now().toUtc().toIso8601String();
final jwtPayload = {
'payload_md5': bodyMd5Hash,
'timestamp': timestampNow,
'method': method,
'url': url,
'user_id': userId,
'api_key': apiKey,
};
final jwt = JWT(
jwtPayload,
header: {'typ': 'JWT', 'alg': 'ES256'},
);
final key = ECPrivateKey(privateKeyPem);
final encodedToken = jwt.sign(key, algorithm: JWTAlgorithm.ES256);
print("✅ Token JWT gerado com sucesso!");
return {'Authorization': encodedToken};
} catch (e) {
print('❌ Erro ao gerar o token JWT: $e');
rethrow;
}
}
4. Utilizando o Header de Autenticação
Após gerar o encoded_header_token (o JWT assinado) conforme demonstrado nos exemplos de código da seção anterior, você deve incluí-lo em suas requisições HTTP para a Noodle External API.
O token JWT é enviado no cabeçalho (header) Authorization.
Para requisições que enviam dados no corpo, como POST ou PUT com um payload JSON, você também deve incluir o cabeçalho Content-Type: application/json.
Authorization: SEU_TOKEN_JWT_GERADO_AQUI
Content-Type: application/json
Substitua SEU_TOKEN_JWT_GERADO_AQUI pelo valor real do token que seu código gerou.
Exemplo de Requisição (cURL)
O exemplo a seguir demonstra como fazer uma requisição POST para o endpoint /external, similar ao usado nos exemplos de geração de token. Você precisará substituir <SEU_TOKEN_JWT_GERADO> pelo token real.
# Substitua <SEU_TOKEN_JWT_GERADO> pelo token JWT que você gerou.
# O corpo da requisição (-d) deve ser o mesmo usado para gerar o 'payload_md5' do seu JWT.
curl -X POST "https://production.api.noodle.cx/external" \
-H "Authorization: <SEU_TOKEN_JWT_GERADO>" \
-H "Content-Type: application/json" \
-d '{"Noodle": "Test"}'
Ao executar este comando cURL (com o token correto), a API da Noodle tentará autenticar sua requisição usando o JWT fornecido e processará o corpo da requisição.
Lembre-se que o payload_md5 dentro do seu JWT deve corresponder exatamente ao hash MD5 do corpo da requisição JSON que você está enviando ('{"Noodle": "Test"}' neste exemplo).
Suporte
Para troca de informações sobre a API, solicitação ou renovação de certificados, ou para esclarecer quaisquer dúvidas sobre o processo de autenticação e uso da Noodle External API, entre em contato conosco através do seguinte e-mail:
api@noodle.cx