Skip to main content

Requests & Conventions

This guide covers the conventions, standards, and best practices for making requests to the Marketiger API.

Base URL​

All API requests should be made to:

https://devapi.marketiger3d.com/v2

HTTP Methods​

The API uses standard HTTP methods:

MethodUsageExample
GETRetrieve resourcesGet projects, models, folders
POSTCreate resources or perform actionsCreate orders, upload models
PUTUpdate resourcesUpdate order status
DELETEDelete resourcesRemove folders, cancel orders

Request Headers​

Required Headers​

All requests should include:

Content-Type: application/json

Authenticated requests must include:

Authorization: Bearer <your_access_token>

Example Headers​

curl -X GET "https://devapi.marketiger3d.com/v2/Project/GetProjects" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Request Body Format​

JSON Format​

All request bodies must be valid JSON:

{
"projectId": "123e4567-e89b-12d3-a456-426614174000",
"orderReference": "ORDER-12345",
"orderContent": {
"ConfigIds": ["config-id-1", "config-id-2"],
"ExternalConfigIds": [],
"StockIds": []
}
}

Content-Type​

Always set the Content-Type header to application/json when sending JSON data.

Response Format​

All API responses follow a consistent format:

Success Response​

{
"success": true,
"data": {
// Response data here
}
}

Error Response​

{
"success": false,
"error": {
"type": "ERROR_TYPE",
"message": "Human-readable error message"
}
}

Data Types​

GUIDs / UUIDs​

Many endpoints use GUIDs (UUIDs) for identifiers:

  • Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  • Example: 123e4567-e89b-12d3-a456-426614174000
  • Usage: Project IDs, Model IDs, Order IDs, Folder IDs

Dates​

Dates are typically returned in ISO 8601 format:

  • Format: YYYY-MM-DDTHH:mm:ssZ
  • Example: 2024-01-15T10:30:00Z

Country Codes​

When specifying countries, use ISO 3166-1 alpha-2 or alpha-3 country codes:

  • Alpha-2: US, GB, NL
  • Alpha-3: USA, GBR, NLD
  • Maximum length: 3 characters

Query Parameters​

For GET requests, parameters are passed as query strings:

GET /Model3D/GetModelData?modelId=123e4567-e89b-12d3-a456-426614174000

URL Encoding​

Always URL-encode query parameters:

const modelId = '123e4567-e89b-12d3-a456-426614174000';
const url = `https://devapi.marketiger3d.com/v2/Model3D/GetModelData?modelId=${encodeURIComponent(modelId)}`;

Common Request Patterns​

Creating an Order​

POST /Order/CreateOrder
{
"firstName": "John",
"lastName": "Doe",
"streetAddress": "123 Main St",
"postal": "10001",
"phoneNumber": "+1234567890",
"email": "customer@example.com",
"city": "New York",
"country": "US",
"countryState": "NY",
"models": [
{
"modelId": "123e4567-e89b-12d3-a456-426614174000",
"quantity": 1
}
],
"shippingMethod": 2503
}

Getting Resources​

# Get all projects
GET /Project/GetProjects

# Get a specific model
GET /Model3D/GetModelData?modelId=guid-here

# Get folders for a project
GET /Folder/GetFolders?projectId=guid-here

Pagination​

Some endpoints support pagination. Check individual endpoint documentation for pagination parameters.

Rate Limiting​

The API implements rate limiting to ensure fair usage:

  • Limit: Varies by endpoint and user tier
  • Response: 429 Too Many Requests when limit exceeded
  • Headers: Check X-RateLimit-* headers for limit information

Handling Rate Limits​

Implement exponential backoff when receiving 429 responses:

async function makeRequestWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);

if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '1');
const delay = retryAfter * Math.pow(2, i); // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay * 1000));
continue;
}

return response;
}

throw new Error('Max retries exceeded');
}

Timeouts​

  • Request Timeout: 30 seconds for most endpoints
  • Long-running Operations: Some endpoints may have extended timeouts

Implement appropriate timeout handling in your HTTP client:

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);

fetch(url, {
...options,
signal: controller.signal
}).finally(() => clearTimeout(timeoutId));

Best Practices​

Error Handling​

Always check the success field in responses:

const response = await fetch(url, options);
const data = await response.json();

if (!data.success) {
console.error('Error:', data.error.message);
// Handle error
return;
}

// Use data.data for successful responses

Request Validation​

Validate data before sending requests:

  • Check required fields are present
  • Validate GUID formats
  • Ensure country codes are valid
  • Verify email addresses are properly formatted

Idempotency​

For order creation and other critical operations, use unique orderReference values to prevent duplicate operations.

Logging​

Log requests and responses for debugging (but never log tokens or sensitive data):

console.log('Request:', {
method: 'POST',
endpoint: '/Order/CreateOrder',
// Don't log: tokens, passwords, sensitive data
});

Code Examples​

JavaScript/TypeScript​

class MarketigerAPI {
constructor(accessToken) {
this.baseUrl = 'https://devapi.marketiger3d.com/v2';
this.accessToken = accessToken;
}

async request(method, endpoint, body = null) {
const options = {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.accessToken}`
}
};

if (body) {
options.body = JSON.stringify(body);
}

const response = await fetch(`${this.baseUrl}${endpoint}`, options);
const data = await response.json();

if (!response.ok || !data.success) {
throw new Error(data.error?.message || 'Request failed');
}

return data.data;
}

async getProjects() {
return this.request('GET', '/Project/GetProjects');
}

async getModelData(modelId) {
return this.request('GET', `/Model3D/GetModelData?modelId=${modelId}`);
}
}

C#​

public class MarketigerAPI
{
private readonly HttpClient _client;
private readonly string _baseUrl = "https://devapi.marketiger3d.com/v2";

public MarketigerAPI(string accessToken)
{
_client = new HttpClient();
_client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
_client.DefaultRequestHeaders.Add("Content-Type", "application/json");
}

public async Task<T> RequestAsync<T>(HttpMethod method, string endpoint, object body = null)
{
var request = new HttpRequestMessage(method, $"{_baseUrl}{endpoint}");

if (body != null)
{
var json = JsonSerializer.Serialize(body);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
}

var response = await _client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
var apiResponse = JsonSerializer.Deserialize<APIResponse<T>>(content);

if (!response.IsSuccessStatusCode || !apiResponse.Success)
{
throw new Exception(apiResponse.Error?.Message ?? "Request failed");
}

return apiResponse.Data;
}

public async Task<List<Project>> GetProjectsAsync()
{
return await RequestAsync<List<Project>>(HttpMethod.Get, "/Project/GetProjects");
}
}

Next Steps​