{
	"info": {
		"_postman_id": "9a84eb7a-3147-4628-b4db-d55f8bd1a81e",
		"name": "eCMR API - 40 PES",
		"description": "Complete REST API for eCMR (electronic Consignment Note) management.\n\nCompliant with:\n- CMR Convention\n- eIDAS Regulation (EU 910/2014)\n- GDPR (EU 2016/679)\n\n**Multi-language Support:**\nThe API supports 6 languages: Portuguese (pt), English (en), Spanish (es), German (de), French (fr), Italian (it).\n\n**Authentication:** Use X-API-Key header with your tenant API key.\n\n**Error Handling:**\nAll error responses include a machine-readable `code` field for i18n mapping:\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"OTP_EXPIRED\",\n    \"message\": \"OTP has expired. Please request a new one.\",\n    \"details\": []\n  }\n}\n```\nSee the 'Error Codes Reference' folder for the complete list of error codes by category.",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
		"_exporter_id": "20604527"
	},
	"item": [
		{
			"name": "Reseller API",
			"description": "For TMS providers and integrators who want to manage multiple client tenants.\n\nResellers can:\n- Create sub-tenants without email verification\n- Receive all webhooks in a centralized endpoint\n- Manage billing for all sub-tenants\n- Each sub-tenant gets its own API key for eCMR operations\n\n**Authentication:** Use X-Master-API-Key header with your reseller master key (rk_live_xxx or rk_test_xxx)",
			"item": [
				{
					"name": "0 Register as Reseller",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 201) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('reseller_id', response.data.reseller_id);",
									"    pm.collectionVariables.set('reseller_signup_email', pm.request.body.raw ? JSON.parse(pm.request.body.raw).email : '');",
									"    console.log('Reseller account created! Reseller ID:', response.data.reseller_id);",
									"    console.log('Check your email for verification link');",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"email\": \"reseller@tms-company.com\",\n  \"company_name\": \"TMS Integration Company\",\n  \"vat_number\": \"PT999888777\",\n  \"address\": \"Rua das Integrações, 100, 4000-000 Porto, Portugal\",\n  \"country_code\": \"PT\",\n  \"max_tenants\": 100\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/signup",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"signup"
							]
						},
						"description": "Register as an eCMR Reseller to manage multiple client tenants.\n\n**Required fields:**\n- email: Your company billing email\n- company_name: Your TMS/integration company name\n- vat_number: EU VAT number (validated)\n- address: Your company full address\n\n**Optional fields:**\n- country_code: Two-letter ISO country code\n- max_tenants: Maximum number of sub-tenants (default: 100)\n\n**What you get:**\n- Master API key (rk_live_xxx) for managing sub-tenants\n- Centralized webhook endpoint\n- Ability to create sub-tenants without email verification"
					},
					"response": []
				},
				{
					"name": "1 Verify Reseller Email",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 200) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('master_api_key', response.data.master_api_key);",
									"    console.log('Reseller email verified!');",
									"    console.log('Master API Key:', response.data.master_api_key);",
									"    console.log('');",
									"    console.log('IMPORTANT: Save your master API key now!');",
									"    console.log('This is the ONLY time it will be shown in full.');",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/signup/verify?token={{reseller_verification_token}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"signup",
								"verify"
							],
							"query": [
								{
									"key": "token",
									"value": "{{reseller_verification_token}}",
									"description": "Paste the token from your reseller verification email here"
								}
							]
						},
						"description": "Verify your reseller email address and receive your master API key.\n\n**What you get:**\n- Master API key (rk_live_xxx) - shown only once!\n- Account activated (status: 'active')\n- Ready to create sub-tenants"
					},
					"response": []
				},
				{
					"name": "2 Create Sub-Tenant",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 201) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('created_tenant_id', response.data.tenant_id);",
									"    pm.collectionVariables.set('created_tenant_api_key', response.data.api_key);",
									"    console.log('Sub-tenant created!');",
									"    console.log('Tenant ID:', response.data.tenant_id);",
									"    console.log('API Key:', response.data.api_key);",
									"    console.log('');",
									"    console.log('The sub-tenant can now use this API key for eCMR operations.');",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"company_name\": \"Client Transport ABC\",\n  \"vat_number\": \"PT123456789\",\n  \"company_type\": \"carrier\",\n  \"address\": \"Rua do Cliente, 50, 1000-000 Lisboa, Portugal\",\n  \"email\": \"contact@client-abc.com\",\n  \"reseller_reference\": \"CLI-00123\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/tenants",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"tenants"
							]
						},
						"description": "Create a new sub-tenant for one of your clients. No email verification required!\n\n**Required fields:**\n- company_name: Client's company name\n- vat_number: Client's VAT number (validated)\n- company_type: 'consignor', 'consignee', or 'carrier'\n- address: Client's full address\n\n**Optional fields:**\n- email: Client's email (optional for managed tenants)\n- reseller_reference: Your internal reference ID for this client\n\n**Response includes:**\n- tenant_id: The sub-tenant's public ID\n- api_key: The sub-tenant's API key for eCMR operations\n\n**Important:** The API key is returned immediately. The sub-tenant can start using the eCMR API right away."
					},
					"response": []
				},
				{
					"name": "3 List Sub-Tenants",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/tenants?page=1&per_page=20",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"tenants"
							],
							"query": [
								{
									"key": "page",
									"value": "1"
								},
								{
									"key": "per_page",
									"value": "20"
								},
								{
									"key": "status",
									"value": "active",
									"disabled": true
								},
								{
									"key": "search",
									"value": "ABC",
									"disabled": true
								}
							]
						},
						"description": "List all sub-tenants managed by this reseller.\n\n**Optional filters:**\n- status: Filter by status ('active', 'suspended')\n- search: Search by company name\n- page: Page number (default: 1)\n- per_page: Items per page (default: 20)"
					},
					"response": []
				},
				{
					"name": "4 Get Sub-Tenant Details",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/tenants/{{created_tenant_id}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"tenants",
								"{{created_tenant_id}}"
							]
						},
						"description": "Get detailed information about a specific sub-tenant, including usage statistics."
					},
					"response": []
				},
				{
					"name": "5 Suspend Sub-Tenant",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/tenants/{{created_tenant_id}}/suspend",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"tenants",
								"{{created_tenant_id}}",
								"suspend"
							]
						},
						"description": "Suspend a sub-tenant. The tenant's API key will stop working immediately."
					},
					"response": []
				},
				{
					"name": "6 Activate Sub-Tenant",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/tenants/{{created_tenant_id}}/activate",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"tenants",
								"{{created_tenant_id}}",
								"activate"
							]
						},
						"description": "Reactivate a suspended sub-tenant."
					},
					"response": []
				},
				{
					"name": "7 Regenerate Sub-Tenant API Key",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 200) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('created_tenant_api_key', response.data.api_key);",
									"    console.log('API key regenerated!');",
									"    console.log('New API Key:', response.data.api_key);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/tenants/{{created_tenant_id}}/regenerate_api_key",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"tenants",
								"{{created_tenant_id}}",
								"regenerate_api_key"
							]
						},
						"description": "Regenerate the API key for a sub-tenant. The old key will be invalidated immediately."
					},
					"response": []
				},
				{
					"name": "8 Configure Reseller Webhook",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "PUT",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"url\": \"https://your-tms.com/webhooks/ecmr\",\n  \"events\": [\n    \"document.created\",\n    \"document.status_changed\",\n    \"signature.completed\"\n  ]\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/webhook",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"webhook"
							]
						},
						"description": "Configure a centralized webhook endpoint to receive events from ALL sub-tenants.\n\n**Webhook payload includes:**\n- reseller_id: Your reseller ID\n- tenant_id: The sub-tenant's ID\n- reseller_reference: Your internal reference for the client\n- vat_number: The sub-tenant's VAT number\n- Event-specific data\n\nThis allows you to route events to the correct internal system based on your reference."
					},
					"response": []
				},
				{
					"name": "9 Test Reseller Webhook",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/webhook/test",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"webhook",
								"test"
							]
						},
						"description": "Send a test webhook to your configured endpoint to verify it's working correctly."
					},
					"response": []
				},
				{
					"name": "10 View Reseller Profile",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/profile",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"profile"
							]
						},
						"description": "Get your reseller profile including tenant limits and usage statistics."
					},
					"response": []
				},
				{
					"name": "11 View Aggregated Usage",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/billing/usage?start_date=2025-01-01&end_date=2025-01-31",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"reseller",
								"billing",
								"usage"
							],
							"query": [
								{
									"key": "start_date",
									"value": "2025-01-01"
								},
								{
									"key": "end_date",
									"value": "2025-01-31"
								}
							]
						},
						"description": "Get aggregated usage statistics across all sub-tenants for billing purposes.\n\n**Query parameters:**\n- start_date: Period start (YYYY-MM-DD)\n- end_date: Period end (YYYY-MM-DD)\n\nDefaults to current month if not specified."
					},
					"response": []
				}
			]
		},
		{
			"name": "Getting Started",
			"item": [
				{
					"name": "1 Create Account",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 201) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('tenant_id', response.data.tenant_id);",
									"    pm.collectionVariables.set('signup_email', pm.request.body.raw ? JSON.parse(pm.request.body.raw).email : '');",
									"    console.log('Account created! Tenant ID:', response.data.tenant_id);",
									"    console.log('Check your email for verification link');",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"email\": \"developer@mycompany.com\",\n  \"company_name\": \"My Transport Company\",\n  \"vat_number\": \"PT123456789\",\n  \"company_type\": \"carrier\",\n  \"address\": \"Rua do Transporte, 123, 4100-000 Porto, Portugal\",\n  \"country_code\": \"PT\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/signup",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"signup"
							]
						},
						"description": "Create your eCMR API account. You'll receive a verification email.\n\n**Required fields:**\n- email: Your company email\n- company_name: Your company name\n- vat_number: EU VAT number (validated)\n- company_type: Your role in eCMRs - 'consignor', 'consignee', or 'carrier'. This determines which party's data is auto-populated when creating eCMRs.\n- address: Your company full address (street, postal code, city, country)\n\n**Optional fields:**\n- country_code: Two-letter ISO country code (e.g., 'PT', 'DE', 'ES') - auto-detected from VAT number if not provided\n- rate_limit_per_minute: Custom rate limit (default: 60)\n\n**What happens:**\n- Account created with status 'pending_verification'\n- Verification email sent\n- You get a tenant_id\n\n**Rate limit:** 5 signups per IP per hour\n\n**Next step:** Check your email and copy the verification token from the link."
					},
					"response": []
				},
				{
					"name": "2 Verify Email & Get API Key",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 200) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('api_key', response.data.api_key);",
									"    console.log('Email verified!');",
									"    console.log('API Key:', response.data.api_key);",
									"    console.log('');",
									"    console.log('IMPORTANT: Save your API key now!');",
									"    console.log('This is the ONLY time it will be shown in full.');",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/signup/verify?token={{verification_token}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"signup",
								"verify"
							],
							"query": [
								{
									"key": "token",
									"value": "{{verification_token}}",
									"description": "Paste the token from your verification email here"
								}
							]
						},
						"description": "Verify your email address and receive your API key.\n\n**How to get the token:**\n1. Check your email inbox\n2. Open the verification email from ecmr@40pes.pt\n3. Copy the token from the link\n4. Paste it in the {{verification_token}} variable\n\n**What you get:**\n- Your API key (shown only once!)\n- Account activated (status: 'active')\n- Rate limit: 60 requests/minute (default)\n- Ready to use the API"
					},
					"response": []
				},
				{
					"name": "3 Test API Key",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 200) {",
									"    console.log('API Key is valid!');",
									"    const response = pm.response.json();",
									"    console.log('Tenant:', response.data.name);",
									"    console.log('Rate Limit:', response.data.rate_limit_per_minute, 'req/min');",
									"} else if (pm.response.code === 401) {",
									"    console.log('ERROR: Invalid API Key. Check your api_key variable.');",
									"} else {",
									"    console.log('Unexpected response:', pm.response.code);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/profile",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"tenant",
								"profile"
							]
						},
						"description": "Test that your API key is working by fetching your tenant profile.\n\n**Expected result:** 200 OK with your tenant profile\n\n**If you get 401 Unauthorized:**\n- Check that your api_key variable is set correctly\n- Make sure you completed the email verification step\n\n**What you'll see:**\n- Your company name\n- API key (masked)\n- Rate limit configuration\n- Account status"
					},
					"response": []
				},
				{
					"name": "4 Create Your First eCMR",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 201) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('cmr_number', response.data.cmr_number);",
									"    console.log('eCMR created!');",
									"    console.log('CMR Number:', response.data.cmr_number);",
									"    console.log('Status:', response.data.status);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"document\": {\n    \"external_reference\": \"MY-FIRST-CMR-001\",\n    \"carrier\": {\n      \"name\": \"My Transport Company\",\n      \"address\": \"Rua do Transporte, 123, 4100-000 Porto, Portugal\",\n      \"vat_number\": \"PT123456789\",\n      \"country\": \"PT\",\n      \"phone\": \"+351910000001\",\n      \"email\": \"carrier@mycompany.com\"\n    },\n    \"consignor\": {\n      \"name\": \"Shipper Company Ltd\",\n      \"address\": \"Shipping Street, 456, 1000-000 Lisboa, Portugal\",\n      \"country\": \"PT\",\n      \"vat_number\": \"PT987654321\",\n      \"email\": \"shipper@example.pt\",\n      \"phone\": \"+351912345678\",\n      \"contact_person\": \"Maria Shipper\"\n    },\n    \"consignee\": {\n      \"name\": \"Receiver GmbH\",\n      \"address\": \"Empfangerstrasse 789, 10115 Berlin, Germany\",\n      \"country\": \"DE\",\n      \"vat_number\": \"DE123456789\",\n      \"email\": \"receiver@example.de\",\n      \"phone\": \"+49301234567\",\n      \"contact_person\": \"Hans Receiver\"\n    },\n    \"goods\": [\n      {\n        \"description\": \"Electronic components for automotive industry\",\n        \"quantity\": 10,\n        \"packaging\": \"pallets\",\n        \"weight_kg\": 2500,\n        \"volume_m3\": 12,\n        \"marks_and_numbers\": \"LOT-2025-DEMO-001\",\n        \"statistical_number\": \"8542.31\",\n        \"dangerous_goods\": false\n      }\n    ],\n    \"transport\": {\n      \"vehicle_registration\": \"12-AB-34\",\n      \"trailer_registration\": \"56-CD-78\",\n      \"driver_name\": \"John Driver\",\n      \"driver_license\": \"P-1234567\",\n      \"driver_phone\": \"+351935000000\",\n      \"loading_place_name\": \"Main Warehouse\",\n      \"loading_place_address\": \"Lisboa, Portugal\",\n      \"delivery_place_name\": \"Distribution Center\",\n      \"delivery_place_address\": \"Berlin, Germany\",\n      \"loading_date\": \"2025-01-20\",\n      \"delivery_date\": \"2025-01-22\"\n    },\n    \"consignor_observations\": \"Goods packed on 10 standard EUR pallets. 2 pallets with reinforced packaging due to fragile contents. Handle with care. Keep dry.\",\n    \"instructions\": {\n      \"observations\": \"Side loading required. Stack maximum 2 pallets.\",\n      \"payment_terms\": \"collect\",\n      \"documents_attached\": [\"Invoice\", \"Packing List\"]\n    },\n    \"metadata\": {\n      \"demo\": true,\n      \"created_from\": \"Getting Started Guide\"\n    }\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents"
							]
						},
						"description": "Create your first eCMR document.\n\n**Important:** Your tenant is configured as a 'carrier', so:\n- The carrier's base data (name, address, country, vat_number, email) is automatically populated from your tenant profile\n- If you try to specify carrier base fields, you'll get an error\n\n**If your tenant was configured as 'consignor' or 'consignee':**\n- That party's base data would be auto-populated instead\n- You'd need to provide full data for the other parties\n\n**Driver information** is provided in the `transport` object:\n- `driver_name`: Name of the driver\n- `driver_license`: Driver's license number\n- `driver_phone`: Driver's phone number\n- `driver_email`: Driver's email (optional)\n\n**Goods object includes:**\n- `statistical_number` (Box 10): HS/NC code for customs\n\n**Observation fields (top-level):**\n- `consignor_observations` (Box 13): Instructions and observations from the shipper\n- `carrier_observations` (Box 18): Carrier reservations and remarks\n- `consignee_observations`: Receiver notes\n\n**Instructions object (CMR Boxes):**\n- `payment_terms` (Box 14): Payment terms - 'prepaid' or 'collect'\n- `cash_on_delivery` (Box 15): COD amount if applicable\n- `special_agreements` (Box 19): Special transport agreements\n- `documents_attached` (Box 5): List of attached documents\n\n**Status after creation:** `draft`\n\n**Next step:** Issue the document to make it active."
					},
					"response": []
				},
				{
					"name": "5 Issue Document (Draft -> Issued)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"location\": \"Lisboa, Portugal\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/lifecycle/issue",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"lifecycle",
								"issue"
							]
						},
						"description": "Issue the document to make it active.\n\n**Transition:** draft -> issued\n\n**What happens:**\n- Document becomes active\n- Ready for carrier acceptance\n- Platform signature applied"
					},
					"response": []
				},
				{
					"name": "6 Update Loading Info (Before Signatures)",
					"request": {
						"method": "PATCH",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"document\": {\n    \"timestamps\": {\n      \"loading_started_at\": \"2025-01-20T08:00:00Z\",\n      \"loading_completed_at\": \"2025-01-20T11:30:00Z\"\n    },\n    \"carrier_observations\": \"Waiting time at loading: 3h30. Consignor warehouse not ready on arrival at 08:00. Loading only started at 10:00. All 10 pallets verified and loaded by 11:30.\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}"
							]
						},
						"description": "**SCENARIO: Carrier adds loading delay info BEFORE signatures**\n\n**What's happening:**\n- Driver arrived at 08:00 but warehouse wasn't ready\n- Loading only completed at 11:30 (3h30 waiting time)\n- Carrier documents this delay as a reservation/observation\n\n**Why do this BEFORE signatures?**\n- Consignor will sign WITH this information visible\n- Both parties acknowledge the delay (CMR Article 8 compliance)\n- The signature snapshot will include these observations\n- No disputes later about waiting time charges\n\n**Timing matters:**\n- If called BEFORE signatures: All parties will sign with this info\n- If called AFTER Consignor signs: Info recorded but marked as 'not signed by Consignor'\n\n**Editable fields (in issued/accepted/delivered states):**\n- `loading_started_at`, `loading_completed_at`\n- `delivery_started_at`, `delivery_completed_at`\n- `carrier_observations`\n- `vehicle_registration`, `trailer_registration`\n- `consignor_observations` (until Consignor signs)\n- `consignee_observations` (until Consignee signs)\n\n**Result:** When Consignor signs in step 9, their signature snapshot includes the loading times and carrier observations. This is verifiable via the `integrity` field in the document response."
					},
					"response": []
				},
				{
					"name": "7 Request Consignor Signature",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 201) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('consignor_signature_id', response.data.id);",
									"    pm.collectionVariables.set('consignor_share_token', response.data.share_token);",
									"    console.log('Consignor signature requested!');",
									"    console.log('Share Token:', response.data.share_token);",
									"    console.log('Signature ID:', response.data.id);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signatory_role\": \"consignor\",\n  \"signatory_name\": \"Maria Shipper\",\n  \"contact\": \"shipper@example.pt\",\n  \"signature_type\": \"remote\",\n  \"preferred_locale\": \"pt\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures"
							]
						},
						"description": "Request signature from consignor (shipper) using remote OTP.\n\n**Note:** The consignor will sign a document that now includes the loading delay info added in step 6. Their signature snapshot will capture this state.\n\n**Signature type: remote (OTP)**\n- For remote signatures, the OTP validation automatically completes the signature\n- No biometric data or signature image required\n- Ideal for parties not physically present\n\n**Parameters:**\n- signatory_role: consignor, carrier, or consignee\n- signatory_name: Name of the person signing\n- contact: Email or phone for OTP delivery\n- signature_type: remote (OTP-only signature)\n- preferred_locale: Language for OTP email (pt, en, es, de, fr, it)\n\n**What happens:**\n- Signature request created with status 'pending'\n- OTP sent to consignor's email (in Portuguese)\n- Share token generated\n\n**Next step:** Validate OTP to complete the signature."
					},
					"response": []
				},
				{
					"name": "8 Validate Consignor OTP",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"otp_code\": \"123456\",\n  \"geolocation\": {\n    \"latitude\": 38.736946,\n    \"longitude\": -9.142685,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{consignor_signature_id}}/validate_otp",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{consignor_signature_id}}",
								"validate_otp"
							]
						},
						"description": "Validate OTP code sent to consignor's email.\n\n**For remote signatures (like this one):**\n- OTP validation automatically COMPLETES the signature\n- No separate /sign endpoint call needed\n- Signature status changes directly to 'completed'\n\n**What happens:**\n- OTP code verified (6-digit code from email)\n- Signature completed automatically\n- Document snapshot captured at this moment\n- Geolocation recorded as evidence\n\n**Response includes:**\n- completed: true\n- signed_at: timestamp\n- method: 'remote_otp'\n\n**Next step:** Request carrier signature (in_person type)."
					},
					"response": []
				},
				{
					"name": "9 Sign as Consignor",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signature_image\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n  \"biometric_data\": {\n    \"strokes\": [\n      {\n        \"index\": 0,\n        \"points\": [\n          {\"x\": 10.5, \"y\": 20.3, \"time\": 0, \"pressure\": 0.5},\n          {\"x\": 12.8, \"y\": 22.1, \"time\": 10, \"pressure\": 0.6},\n          {\"x\": 15.2, \"y\": 24.5, \"time\": 20, \"pressure\": 0.65}\n        ],\n        \"duration\": 500,\n        \"point_count\": 45\n      }\n    ],\n    \"stroke_count\": 1,\n    \"total_points\": 45,\n    \"total_time\": 500,\n    \"average_speed\": 0.125,\n    \"average_pressure\": 0.62\n  },\n  \"geolocation\": {\n    \"latitude\": 38.736946,\n    \"longitude\": -9.142685,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{consignor_signature_id}}/sign",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{consignor_signature_id}}",
								"sign"
							]
						},
						"description": "**SKIP THIS STEP for remote signatures!**\n\nFor remote (OTP) signatures, the signature is automatically completed when you validate the OTP in step 8. This /sign endpoint is only needed for in_person signatures.\n\n**When is this needed?**\n- in_person: Required (biometric data + signature image)\n- remote: NOT needed (OTP validation completes it)\n- certificate: Required (digital signature data)\n- without_signature: NOT needed (completed on request)\n\n**Since we used remote signature for consignor, skip to step 10.**"
					},
					"response": []
				},
				{
					"name": "10 Request Carrier Signature",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 201) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('carrier_signature_id', response.data.id);",
									"    pm.collectionVariables.set('carrier_share_token', response.data.share_token);",
									"    console.log('Carrier signature requested!');",
									"    console.log('Share Token:', response.data.share_token);",
									"    console.log('Signature ID:', response.data.id);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signatory_role\": \"carrier\",\n  \"signatory_name\": \"John Driver\",\n  \"contact\": \"driver@mycompany.com\",\n  \"signature_type\": \"in_person\",\n  \"preferred_locale\": \"en\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures"
							]
						},
						"description": "Request signature from carrier (driver) using in_person biometric signature.\n\n**Signature type: in_person**\n- Driver signs directly on a device (tablet/phone)\n- Captures signature image + biometric data (strokes, pressure, timing)\n- eIDAS-compliant with full audit trail\n- Ideal when the signer is physically present\n\n**What happens:**\n- Signature request created with status 'pending'\n- NO OTP sent (in_person doesn't require email verification)\n- Ready for biometric signing immediately\n\n**Next step:** For in_person signatures you can skip OTP validation and go directly to the /sign endpoint, OR validate OTP first for additional security."
					},
					"response": []
				},
				{
					"name": "11 Validate Carrier OTP",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"otp_code\": \"123456\",\n  \"geolocation\": {\n    \"latitude\": 41.157944,\n    \"longitude\": -8.629105,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{carrier_signature_id}}/validate_otp",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{carrier_signature_id}}",
								"validate_otp"
							]
						},
						"description": "**OPTIONAL for in_person signatures!**\n\nFor in_person signatures, OTP validation is optional. You can skip directly to step 12 (/sign) if the driver is physically present and you trust their identity.\n\n**When to use OTP for in_person:**\n- Additional identity verification layer\n- Company policy requires dual-factor\n- Remote supervision of signing process\n\n**For this demo, skip to step 12 (Sign as Carrier).**"
					},
					"response": []
				},
				{
					"name": "12 Sign as Carrier",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signature_image\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n  \"biometric_data\": {\n    \"strokes\": [\n      {\n        \"index\": 0,\n        \"points\": [\n          {\"x\": 10.5, \"y\": 20.3, \"time\": 0, \"pressure\": 0.5},\n          {\"x\": 12.8, \"y\": 22.1, \"time\": 10, \"pressure\": 0.6},\n          {\"x\": 15.2, \"y\": 24.5, \"time\": 20, \"pressure\": 0.65}\n        ],\n        \"duration\": 500,\n        \"point_count\": 45\n      }\n    ],\n    \"stroke_count\": 1,\n    \"total_points\": 45,\n    \"total_time\": 500,\n    \"average_speed\": 0.125,\n    \"average_pressure\": 0.62\n  },\n  \"geolocation\": {\n    \"latitude\": 41.157944,\n    \"longitude\": -8.629105,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{carrier_signature_id}}/sign",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{carrier_signature_id}}",
								"sign"
							]
						},
						"description": "Complete carrier signature with biometric data (in_person signature).\n\n**Required data for in_person:**\n- signature_image: Base64 PNG of the drawn signature\n- biometric_data: Stroke data including points, timing, and pressure\n- geolocation: GPS coordinates where signing occurred\n\n**Biometric validation:**\n- Minimum 1 stroke with 3+ points\n- Minimum 500ms signing duration (prevents auto-signing)\n- Confidence score calculated from stroke analysis\n\n**What happens:**\n- Biometric data analyzed for authenticity\n- eIDAS-compliant signature created\n- Document snapshot captured\n- If both carrier + consignor signed: Document auto-transitions to 'accepted'\n\n**Next step:** Request consignee signature at delivery (using without_signature type)."
					},
					"response": []
				},
				{
					"name": "13 Request Consignee Signature",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"if (pm.response.code === 201) {",
									"    const response = pm.response.json();",
									"    pm.collectionVariables.set('consignee_signature_id', response.data.id);",
									"    pm.collectionVariables.set('consignee_share_token', response.data.share_token);",
									"    console.log('Consignee signature requested!');",
									"    console.log('Share Token:', response.data.share_token);",
									"    console.log('Signature ID:', response.data.id);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signatory_role\": \"consignee\",\n  \"signature_type\": \"without_signature\",\n  \"geolocation\": {\n    \"latitude\": 52.520008,\n    \"longitude\": 13.404954,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures"
							]
						},
						"description": "Register delivery acknowledgment when consignee cannot sign (without_signature).\n\n**Signature type: without_signature**\n- Used when the counterparty cannot provide a signature\n- Common scenarios: no one present at delivery, refusal to sign, unattended delivery\n- Only allowed for consignor and consignee roles (NOT carrier)\n\n**Required data:**\n- signatory_role: consignee (or consignor)\n- signature_type: without_signature\n- geolocation: GPS coordinates as evidence (required!)\n\n**Optional data:**\n- signatory_name: Name of the person (if known). Can be omitted when person is absent or refuses to identify.\n\n**NO contact needed** - no OTP is sent\n\n**What happens:**\n- Signature immediately completed with status 'completed'\n- Geolocation + timestamp recorded as evidence\n- Document can progress to 'delivered' status\n- Document CANNOT progress to 'completed' (requires proper signatures)\n\n**Important:** Documents with without_signature remain in 'delivered' state permanently. They cannot reach 'completed' status, which requires all three parties to provide actual signatures.\n\n**No further steps needed** - skip to step 18 (Download PDF)."
					},
					"response": []
				},
				{
					"name": "14 Validate Consignee OTP",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"otp_code\": \"123456\",\n  \"geolocation\": {\n    \"latitude\": 52.520008,\n    \"longitude\": 13.404954,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{consignee_signature_id}}/validate_otp",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{consignee_signature_id}}",
								"validate_otp"
							]
						},
						"description": "**SKIP THIS STEP for without_signature!**\n\nFor without_signature type used in step 13, the signature is automatically completed on request. No OTP validation needed.\n\n**When is OTP validation needed?**\n- remote: Required (OTP validates and completes)\n- in_person: Optional (additional security layer)\n- certificate: Required (verifies identity before cert signing)\n- without_signature: NOT needed (completed on request)\n\n**Since we used without_signature for consignee, skip to step 18 (Download PDF).**"
					},
					"response": []
				},
				{
					"name": "17 Sign as Consignee",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signature_image\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n  \"biometric_data\": {\n    \"strokes\": [\n      {\n        \"index\": 0,\n        \"points\": [\n          {\"x\": 10.5, \"y\": 20.3, \"time\": 0, \"pressure\": 0.5},\n          {\"x\": 12.8, \"y\": 22.1, \"time\": 10, \"pressure\": 0.6},\n          {\"x\": 15.2, \"y\": 24.5, \"time\": 20, \"pressure\": 0.65}\n        ],\n        \"duration\": 500,\n        \"point_count\": 45\n      }\n    ],\n    \"stroke_count\": 1,\n    \"total_points\": 45,\n    \"total_time\": 500,\n    \"average_speed\": 0.125,\n    \"average_pressure\": 0.62\n  },\n  \"geolocation\": {\n    \"latitude\": 52.520008,\n    \"longitude\": 13.404954,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{consignee_signature_id}}/sign",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{consignee_signature_id}}",
								"sign"
							]
						},
						"description": "**SKIP THIS STEP for without_signature!**\n\nFor without_signature type used in step 13, the signature is automatically completed on request. No /sign endpoint call needed.\n\n**When is /sign endpoint needed?**\n- in_person: Required (biometric data + signature image)\n- certificate: Required (digital signature data)\n- remote: NOT needed (OTP validation completes it)\n- without_signature: NOT needed (completed on request)\n\n**Since we used without_signature for consignee, skip to step 18.**\n\n**Note about document status:**\nWith without_signature, the document will remain in 'delivered' status. It cannot transition to 'completed' because that requires all three parties to provide actual signatures."
					},
					"response": []
				},
				{
					"name": "18 Update Delivery Issue (After Consignee Signature)",
					"request": {
						"method": "PATCH",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"document\": {\n    \"timestamps\": {\n      \"delivery_started_at\": \"2025-01-22T14:00:00Z\",\n      \"delivery_completed_at\": \"2025-01-22T16:30:00Z\"\n    },\n    \"carrier_observations\": \"Waiting time at loading: 3h30. Consignor warehouse not ready on arrival at 08:00. Loading only started at 10:00. All 10 pallets verified and loaded by 11:30.\\n---\\nDelivery issue: 1 pallet (LOT-2025-DEMO-001-P07) found with water damage during unloading. Consignee refused to acknowledge damage in signature. Damage documented with photos (ref: DMG-20250122-001). Pallet segregated for inspection.\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}"
							]
						},
						"description": "**SCENARIO: Carrier adds delivery info after consignee acknowledgment**\n\n**What's happening:**\n- Driver completed delivery with without_signature (no one present to sign)\n- Unloading completed, but driver noticed 1 pallet with damage\n- Carrier documents the issue after the without_signature acknowledgment\n\n**Why document this?**\n- Even with without_signature, carrier can add observations\n- Creates audit trail of delivery conditions\n- Important for insurance/claims documentation\n- The system tracks when observations were added\n\n**Result:** The document shows:\n- Consignee entry has without_signature type with geolocation evidence\n- Carrier observations added with timestamp\n- Full transparency about delivery conditions\n\n**CMR Compliance:** Carrier's reservations are recorded with clear timestamps showing when they were documented."
					},
					"response": []
				},
				{
					"name": "17 Download PDF",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/pdf",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"pdf"
							]
						},
						"description": "Download the eCMR as PDF.\n\n**What you get:**\n- Professional bilingual PDF (carrier language + English)\n- All signatures displayed with their types\n- Geolocation and timestamps for each signature\n- QR code for verification\n\n**For without_signature entries (like our consignee):**\n- Displayed with orange warning: '[ NO SIGNATURE ]'\n- Shows 'Registered at:' timestamp prominently\n- Notes 'Acknowledged with geolocation and timestamp only'\n- GPS coordinates displayed as evidence\n\n**Document status:** 'delivered' (not 'completed' due to without_signature)"
					},
					"response": []
				},
				{
					"name": "21 Download PDF (Bilingual)",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/pdf?locale=de",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"pdf"
							],
							"query": [
								{
									"key": "locale",
									"value": "de",
									"description": "Secondary language for bilingual PDF (pt, en, es, de, fr, it)"
								}
							]
						},
						"description": "Download the eCMR as a bilingual PDF.\n\n**locale parameter:**\n- pt: Portuguese\n- en: English\n- es: Spanish\n- de: German\n- fr: French\n- it: Italian\n\n**What you get:**\n- Bilingual PDF with primary language + selected secondary language\n- Useful for international transport\n- All signatures included"
					},
					"response": []
				},
				{
					"name": "22 Download PDF (As Signed)",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/pdf/consignor",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"pdf",
								"consignor"
							],
							"query": [
								{
									"key": "locale",
									"value": "pt",
									"description": "Secondary language for bilingual PDF (pt, en, es, de, fr, it)",
									"disabled": true
								},
								{
									"key": "inline",
									"value": "true",
									"description": "Display inline in browser instead of download",
									"disabled": true
								}
							]
						},
						"description": "Download the eCMR PDF as it was at the moment a specific role signed.\n\n**URL Format:**\n- `/pdf/consignor` - Document as signed by the consignor (sender)\n- `/pdf/carrier` - Document as signed by the carrier (transporter)\n- `/pdf/consignee` - Document as signed by the consignee (receiver)\n\n**Purpose:**\nEssential for legal disputes and audits. Each signature captures a snapshot of the document at that exact moment. This endpoint generates a PDF showing exactly what that party saw and agreed to when they signed.\n\n**What you get:**\n- Yellow banner indicating 'DOCUMENT AS SIGNED'\n- Shows role, signatory name, and signature timestamp\n- Displays truncated SHA256 hash for integrity verification\n- Gray color scheme (document wasn't 'completed' at signature time)\n- Only signatures that existed at or before this signature moment\n\n**Query parameters:**\n- locale: Secondary language (pt, en, es, de, fr, it)\n- inline: Set to 'true' to display in browser instead of download\n\n**Error responses:**\n- 400 Bad Request: Invalid role (must be consignor, carrier, or consignee)\n- 404 Not Found: No completed signature found for the specified role"
					},
					"response": []
				}
			],
			"description": "Complete walkthrough from signup to completing your first eCMR document.\n\nFollow these requests in order:\n\n1. Create Account\n2. Verify Email & Get API Key\n3. Test API Key\n4. Create Your First eCMR\n5. Issue Document (Draft -> Issued)\n6. Request Consignor Signature\n7. Validate Consignor OTP\n8. Sign as Consignor\n9. Request Carrier Signature\n10. Validate Carrier OTP\n11. Sign as Carrier\n12. Accept by Carrier (Issued -> Accepted)\n13. Request Consignee Signature\n14. Deliver Cargo (Accepted -> Delivered)\n15. Validate Consignee OTP\n16. Sign as Consignee\n17. Complete eCMR (Delivered -> Completed)\n18. Download PDF\n19. Download PDF (Bilingual)\n20. Download PDF (As Signed)"
		},
		{
			"name": "Account Management",
			"item": [
				{
					"name": "Create Account",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"email\": \"developer@mycompany.com\",\n  \"company_name\": \"My Transport Company\",\n  \"vat_number\": \"PT123456789\",\n  \"company_type\": \"carrier\",\n  \"address\": \"Rua do Transporte, 123, 4100-000 Porto, Portugal\",\n  \"country_code\": \"PT\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/signup",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"signup"
							]
						},
						"description": "Create a new eCMR API account. You'll receive a verification email with a link to activate your account and get your API key.\n\n**Required fields:**\n- email: Your company email\n- company_name: Your company name\n- vat_number: EU VAT number (validated)\n- company_type: Your role in eCMRs - 'consignor', 'consignee', or 'carrier'\n- address: Your company full address\n\n**Optional:**\n- country_code: Two-letter ISO country code (auto-detected from VAT if not provided)\n- rate_limit_per_minute: Custom rate limit (default: 60)\n\n**What happens:**\n1. Account created with status 'pending_verification'\n2. Verification email sent to your inbox\n3. You get a tenant_id\n4. Token expires in 24 hours\n\n**Rate limit:** 5 signups per IP per hour"
					},
					"response": []
				},
				{
					"name": "Verify Email",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [
							{
								"key": "Accept",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/signup/verify?token=YOUR_VERIFICATION_TOKEN",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"signup",
								"verify"
							],
							"query": [
								{
									"key": "token",
									"value": "YOUR_VERIFICATION_TOKEN",
									"description": "Token from verification email"
								}
							]
						},
						"description": "Verify your email address and activate your account.\n\n**How to get the token:**\n1. Check your email inbox\n2. Open the verification email from ecmr@40pes.pt\n3. Click the link or copy the token from the URL\n\n**What you get:**\n- Your API key (shown only once!)\n- Account activated (status: 'active')\n- Rate limit: 60 requests/minute (default)\n- Ready to use the API\n\n**Browser access:**\nIf you click the link in your browser, you'll see a nice landing page with your API key and quick start instructions.\n\n**API access:**\nIf you use Accept: application/json header, you'll get JSON response with your API key."
					},
					"response": []
				},
				{
					"name": "Resend Verification Email",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"email\": \"developer@mycompany.com\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/signup/resend_verification",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"signup",
								"resend_verification"
							]
						},
						"description": "Resend the verification email if:\n- You didn't receive the original email\n- The verification link expired (24h expiration)\n- You deleted the email accidentally\n\n**What happens:**\n- New verification token generated\n- New email sent\n- Old token invalidated\n- New token expires in 24 hours"
					},
					"response": []
				}
			],
			"description": "Signup, verification, and account management (no authentication required)"
		},
		{
			"name": "API Status",
			"item": [
				{
					"name": "Health Check",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/health",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"health"
							]
						},
						"description": "Check API health status. Returns service health, database connectivity, and response times. No authentication required."
					},
					"response": []
				},
				{
					"name": "API Version",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/version",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"version"
							]
						},
						"description": "Get API version information including supported versions and deprecations. No authentication required."
					},
					"response": []
				}
			],
			"description": "Health checks and API version information"
		},
		{
			"name": "Tenant",
			"item": [
				{
					"name": "Get Profile",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/profile",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"tenant",
								"profile"
							]
						},
						"description": "Get your tenant profile including configuration, rate limits, and settings."
					},
					"response": []
				},
				{
					"name": "Update Profile",
					"request": {
						"method": "PUT",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"name\": \"My Company Updated\",\n  \"company_type\": \"carrier\",\n  \"address\": \"Rua do Transporte, 456, 4100-000 Porto, Portugal\",\n  \"country_code\": \"PT\",\n  \"metadata\": {\n    \"department\": \"Logistics\",\n    \"integration_version\": \"2.0\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/profile",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"tenant",
								"profile"
							]
						},
						"description": "Update your tenant profile information.\n\n**Updatable fields:**\n- name: Your company name\n- company_type: Your role in eCMRs - 'consignor', 'consignee', or 'carrier'. When set, your company data will be pre-filled in eCMRs for that role.\n- address: Your company full address (street, postal code, city, country)\n- country_code: Two-letter ISO country code (e.g., 'PT', 'DE', 'ES')\n- metadata: Custom metadata object for your integration"
					},
					"response": []
				},
				{
					"name": "Get Usage Statistics",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/usage",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"tenant",
								"usage"
							]
						},
						"description": "Get your tenant's usage statistics including document counts, signature statistics, and API rate limits."
					},
					"response": []
				},
				{
					"name": "Get Webhook Configuration",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/webhook",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"tenant",
								"webhook"
							]
						},
						"description": "Get your current webhook configuration including URL and subscribed events."
					},
					"response": []
				},
				{
					"name": "Update Webhook",
					"request": {
						"method": "PUT",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"url\": \"https://yourserver.com/webhooks/ecmr\",\n  \"events\": [\n    \"document.created\",\n    \"document.updated\",\n    \"document.status_changed\",\n    \"signature.completed\",\n    \"signature.failed\"\n  ]\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/webhook",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"tenant",
								"webhook"
							]
						},
						"description": "Configure your webhook endpoint. The system will send POST requests to your URL when subscribed events occur. Returns the webhook secret for signature verification."
					},
					"response": []
				},
				{
					"name": "Test Webhook",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/test_webhook",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"tenant",
								"test_webhook"
							]
						},
						"description": "Send a test webhook to your configured endpoint. Use this to verify your webhook receiver is working correctly."
					},
					"response": []
				}
			],
			"description": "Tenant profile, usage statistics, and webhook configuration"
		},
		{
			"name": "Documents",
			"item": [
				{
					"name": "List Documents",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents?page=1&per_page=20",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents"
							],
							"query": [
								{
									"key": "page",
									"value": "1",
									"description": "Page number (default: 1)"
								},
								{
									"key": "per_page",
									"value": "20",
									"description": "Items per page (default: 20)"
								},
								{
									"key": "status",
									"value": "issued",
									"description": "Filter by status: draft, issued, accepted, delivered, completed, cancelled",
									"disabled": true
								},
								{
									"key": "external_reference",
									"value": "REF-001",
									"description": "Filter by external reference",
									"disabled": true
								},
								{
									"key": "created_after",
									"value": "2025-01-01",
									"description": "Filter documents created after this date",
									"disabled": true
								},
								{
									"key": "created_before",
									"value": "2025-12-31",
									"description": "Filter documents created before this date",
									"disabled": true
								},
								{
									"key": "sort_by",
									"value": "created_at",
									"description": "Sort field",
									"disabled": true
								},
								{
									"key": "sort_order",
									"value": "desc",
									"description": "Sort order: asc or desc",
									"disabled": true
								}
							]
						},
						"description": "List all eCMR documents for the authenticated tenant with optional filtering and pagination."
					},
					"response": []
				},
				{
					"name": "Get Document",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}"
							]
						},
						"description": "Get detailed information about a specific eCMR document including all parties, goods, transport details, and signatures."
					},
					"response": []
				},
				{
					"name": "Create Document",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"document\": {\n    \"external_reference\": \"REF-001\",\n    \"carrier\": {\n      \"name\": \"40 PES Transport, Lda\",\n      \"address\": \"Rua do Transporte, 123, 4100-000 Porto, Portugal\",\n      \"vat_number\": \"PT123456789\",\n      \"country\": \"PT\",\n      \"phone\": \"+351910000001\",\n      \"email\": \"carrier@40pes.pt\"\n    },\n    \"consignor\": {\n      \"name\": \"Empresa Expedidora, Lda\",\n      \"address\": \"Av. da Expedicao, 456, 1000-000 Lisboa, Portugal\",\n      \"country\": \"PT\",\n      \"vat_number\": \"PT987654321\",\n      \"email\": \"expedidor@exemplo.pt\",\n      \"phone\": \"+351912345678\",\n      \"contact_person\": \"Joao Expedidor\"\n    },\n    \"consignee\": {\n      \"name\": \"Receiver GmbH\",\n      \"address\": \"Empfangerstrasse 789, 10115 Berlin, Germany\",\n      \"country\": \"DE\",\n      \"vat_number\": \"DE123456789\",\n      \"email\": \"receiver@example.de\",\n      \"phone\": \"+49301234567\",\n      \"contact_person\": \"Hans Muller\"\n    },\n    \"goods\": [\n      {\n        \"description\": \"Pecas metalicas para industria automovel\",\n        \"quantity\": 50,\n        \"packaging\": \"pallets\",\n        \"weight_kg\": 12500,\n        \"volume_m3\": 60,\n        \"marks_and_numbers\": \"LOT-2025-001\",\n        \"statistical_number\": \"7326.90\",\n        \"dangerous_goods\": false\n      }\n    ],\n    \"transport\": {\n      \"vehicle_registration\": \"12-AB-34\",\n      \"trailer_registration\": \"56-CD-78\",\n      \"driver_name\": \"Manuel Silva\",\n      \"driver_license\": \"P-1234567\",\n      \"driver_phone\": \"+351935794288\",\n      \"loading_place_name\": \"Armazém Central\",\n      \"loading_place_address\": \"Lisboa, Portugal\",\n      \"delivery_place_name\": \"Centro Logístico\",\n      \"delivery_place_address\": \"Berlin, Germany\",\n      \"loading_date\": \"2025-01-20\",\n      \"delivery_date\": \"2025-01-22\",\n      \"successive_carriers\": []\n    },\n    \"consignor_observations\": \"Manter seco. Nao empilhar mais de 3 paletes. Handle with care.\",\n    \"instructions\": {\n      \"observations\": \"Carga lateral obrigatoria. Nao empilhar mais de 2 paletes.\",\n      \"payment_terms\": \"collect\",\n      \"special_agreements\": \"FOB Lisboa\",\n      \"cash_on_delivery\": null,\n      \"documents_attached\": [\"Invoice\", \"Packing List\"]\n    },\n    \"metadata\": {\n      \"internal_ref\": \"PO-2025-001\",\n      \"customer_id\": \"CUST-123\",\n      \"priority\": \"normal\"\n    }\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents"
							]
						},
						"description": "Create a new eCMR document. The document will be created in 'draft' status and must be issued to become active."
					},
					"response": []
				},
				{
					"name": "Update Document",
					"request": {
						"method": "PUT",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"document\": {\n    \"goods\": [\n      {\n        \"description\": \"Pecas metalicas para industria automovel - ATUALIZADO\",\n        \"quantity\": 50,\n        \"packaging\": \"pallets\",\n        \"weight_kg\": 12600,\n        \"volume_m3\": 62,\n        \"marks_and_numbers\": \"LOT-2025-001\"\n      }\n    ],\n    \"consignor_observations\": \"2 paletes com embalagem reforcada devido a fragilidade. Mercadoria verificada e conforme. Manter seco. Handle with extreme care.\",\n    \"metadata\": {\n      \"internal_ref\": \"PO-2025-001-REV1\",\n      \"updated_reason\": \"Weight correction after verification\"\n    }\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}"
							]
						},
						"description": "Update an existing eCMR document. Only include the fields you want to update.\n\n**consignor_observations** (Box 13): Sender can add observations about the goods until they sign. This is a top-level field."
					},
					"response": []
				},
				{
					"name": "Delete Document",
					"request": {
						"method": "DELETE",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}"
							]
						},
						"description": "Delete an eCMR document. Only draft documents can be deleted."
					},
					"response": []
				},
				{
					"name": "Search Documents",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/search?q=Berlin",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"search"
							],
							"query": [
								{
									"key": "q",
									"value": "Berlin",
									"description": "Search query (searches in CMR number, parties, goods description, etc.)"
								}
							]
						},
						"description": "Search for eCMR documents by keyword. Searches across CMR number, party names, goods description, etc."
					},
					"response": []
				},
				{
					"name": "Get Statistics",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/statistics",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"statistics"
							]
						},
						"description": "Get statistics about eCMR documents for the tenant including counts by status, this month's documents, etc."
					},
					"response": []
				},
				{
					"name": "Download PDF",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/pdf?inline=false",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"pdf"
							],
							"query": [
								{
									"key": "inline",
									"value": "false",
									"description": "Set to 'true' for inline display, 'false' for download attachment"
								},
								{
									"key": "locale",
									"value": "en",
									"description": "Secondary language for bilingual PDF (pt, en, es, de, fr, it)",
									"disabled": true
								}
							]
						},
						"description": "Download the eCMR document as a PDF file. Includes all document data, parties, goods, transport details, and signatures.\n\n**Query Parameters:**\n- inline: Set to 'true' for inline display, 'false' for download (default)\n- locale: Secondary language for bilingual PDF. Available: pt, en, es, de, fr, it"
					},
					"response": []
				},
				{
					"name": "Download PDF (Bilingual)",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/pdf?locale=de",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"pdf"
							],
							"query": [
								{
									"key": "locale",
									"value": "de",
									"description": "Secondary language for bilingual PDF (pt, en, es, de, fr, it)"
								}
							]
						},
						"description": "Download the eCMR document as a bilingual PDF. The PDF will include the primary language and the specified secondary language.\n\n**Available locales:**\n- pt: Portuguese\n- en: English\n- es: Spanish\n- de: German\n- fr: French\n- it: Italian\n\n**Use cases:**\n- International transport between countries with different languages\n- Authorities inspection in destination country\n- Customer documentation requirements"
					},
					"response": []
				},
				{
					"name": "Get Document History",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/history",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"history"
							]
						},
						"description": "Get the complete audit trail/history of all changes made to the document. Shows version history with timestamps and changes."
					},
					"response": []
				},
				{
					"name": "Check Compliance",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/compliance",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"compliance"
							]
						},
						"description": "Check the document's compliance with CMR Convention and eIDAS requirements. Returns detailed compliance status for each check."
					},
					"response": []
				},
				{
					"name": "Validate Document Data",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"document\": {\n    \"external_reference\": \"REF-001\",\n    \"carrier\": {\n      \"name\": \"40 PES Transport, Lda\",\n      \"vat\": \"PT123456789\"\n    },\n    \"consignor\": {\n      \"name\": \"Empresa Expedidora, Lda\"\n    },\n    \"consignee\": {\n      \"name\": \"Receiver GmbH\"\n    },\n    \"goods\": [\n      {\n        \"description\": \"Pecas metalicas\",\n        \"quantity\": 1,\n        \"packaging\": \"pallets\",\n        \"weight_kg\": 100\n      }\n    ],\n    \"transport\": {\n      \"vehicle_plate\": \"12-AB-34\"\n    }\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/validate",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"validate"
							]
						},
						"description": "Validate document data before creating. Returns validation errors and warnings without creating the document."
					},
					"response": []
				}
			],
			"description": "CRUD operations for eCMR documents"
		},
		{
			"name": "Lifecycle",
			"item": [
				{
					"name": "Get Lifecycle Status",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/lifecycle/status",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"lifecycle",
								"status"
							]
						},
						"description": "Get the current lifecycle status of the document including next required signature, completion status, and all timestamps."
					},
					"response": []
				},
				{
					"name": "Issue Document (Draft -> Issued)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"location\": \"Lisboa, Portugal\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/lifecycle/issue",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"lifecycle",
								"issue"
							]
						},
						"description": "Issue a draft document. This transitions the document from 'draft' to 'issued' status.\n\n**Parameters:**\n- location: Where the document was issued"
					},
					"response": []
				},
				{
					"name": "Cancel Document",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"reason\": \"Encomenda cancelada pelo cliente. Order cancelled by customer due to production delay.\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/lifecycle/cancel",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"lifecycle",
								"cancel"
							]
						},
						"description": "Cancel the document. Only non-completed documents can be cancelled. Provide a reason for the cancellation."
					},
					"response": []
				}
			],
			"description": "Document lifecycle management.\n\n**Automatic Transitions (based on signatures):**\n- issued → accepted: When Carrier signs AND Consignor has signature request\n- accepted → delivered: When Consignee signature is requested AND Carrier has signed\n- delivered → completed: When ALL 3 signatures are completed\n\n**Manual Endpoints:**\n- POST /lifecycle/issue: Emit document (draft → issued)\n- POST /lifecycle/cancel: Cancel document\n- GET /lifecycle/status: Get current status"
		},
		{
			"name": "Signatures",
			"item": [
				{
					"name": "List Signatures",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures"
							]
						},
						"description": "List all signatures for a document including their status, signatory information, and signing timestamps."
					},
					"response": []
				},
				{
					"name": "Get Signature Details",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{signature_id}}"
							]
						},
						"description": "Get detailed information about a specific signature."
					},
					"response": []
				},
				{
					"name": "Request Signature",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signatory_role\": \"consignee\",\n  \"signatory_name\": \"Hans Muller\",\n  \"contact\": \"hans.muller@example.de\",\n  \"signature_type\": \"in_person\",\n  \"preferred_locale\": \"de\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures"
							]
						},
						"description": "Create a signature request for a party. This will generate a share link and optionally send an OTP.\n\n**Parameters:**\n- signatory_role: consignor, carrier, or consignee (required)\n- signatory_name: Name of the person signing (required, except for without_signature)\n- contact: Email or phone for OTP (required for remote)\n- signature_type: in_person, remote, certificate, platform, or without_signature\n- geolocation: Required for without_signature type (latitude, longitude)\n- preferred_locale: Language for emails (pt, en, es, de, fr, it)\n\n**Signature Types:**\n- in_person: Physical signature with OTP validation\n- remote: OTP-based signature without physical presence\n- certificate: Digital certificate signature (eIDAS)\n- platform: System-generated signature\n- without_signature: For cases where counterparty cannot sign (absent/refused). Only for consignor/consignee. Requires geolocation. signatory_name is optional (person may be absent or refuse to identify). Document cannot be completed with this type.\n\n**Response includes:**\n- Signature ID\n- Share token for signing link\n- Share expiration time"
					},
					"response": []
				},
				{
					"name": "Validate OTP",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"otp_code\": \"123456\",\n  \"geolocation\": {\n    \"latitude\": 52.520008,\n    \"longitude\": 13.404954,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/validate_otp",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{signature_id}}",
								"validate_otp"
							]
						},
						"description": "Validate the OTP code sent to the signatory. This is required before signing (unless using device_shared mode).\n\n**Parameters:**\n- otp_code: 6-digit code sent to email/phone (required)\n- geolocation: Location data (optional but recommended)"
					},
					"response": []
				},
				{
					"name": "Sign Document (In Person)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signature_image\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n  \"biometric_data\": {\n    \"strokes\": [\n      {\n        \"index\": 0,\n        \"points\": [\n          {\"x\": 10.5, \"y\": 20.3, \"time\": 0, \"pressure\": 0.5},\n          {\"x\": 12.8, \"y\": 22.1, \"time\": 10, \"pressure\": 0.6},\n          {\"x\": 15.2, \"y\": 24.5, \"time\": 20, \"pressure\": 0.65},\n          {\"x\": 18.1, \"y\": 26.2, \"time\": 30, \"pressure\": 0.7},\n          {\"x\": 21.3, \"y\": 27.8, \"time\": 40, \"pressure\": 0.68}\n        ],\n        \"duration\": 500,\n        \"point_count\": 45\n      },\n      {\n        \"index\": 1,\n        \"points\": [\n          {\"x\": 30.0, \"y\": 15.0, \"time\": 600, \"pressure\": 0.55},\n          {\"x\": 32.5, \"y\": 18.2, \"time\": 610, \"pressure\": 0.6},\n          {\"x\": 35.1, \"y\": 21.4, \"time\": 620, \"pressure\": 0.62}\n        ],\n        \"duration\": 400,\n        \"point_count\": 38\n      }\n    ],\n    \"stroke_count\": 2,\n    \"total_points\": 83,\n    \"total_time\": 1020,\n    \"average_speed\": 0.125,\n    \"average_pressure\": 0.62\n  },\n  \"geolocation\": {\n    \"latitude\": 52.520008,\n    \"longitude\": 13.404954,\n    \"accuracy\": 10\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/sign",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{signature_id}}",
								"sign"
							]
						},
						"description": "Complete the signature with biometric data. This creates an eIDAS-compliant Advanced Electronic Signature (AdES).\n\n**Required for in_person signatures:**\n- signature_image: Base64-encoded PNG/JPEG of the signature\n- biometric_data: Stroke data with pressure, speed, timing\n\n**Optional:**\n- geolocation: Location data\n- signer_info: Additional signer information\n\n**Prerequisites:** OTP must be validated first."
					},
					"response": []
				},
				{
					"name": "Sign Document (Certificate)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"signed_data_hash\": \"a1b2c3d4e5f6...\",\n  \"digital_signature\": \"MEUCIQD...\",\n  \"certificate_fingerprint\": \"SHA256:AB:CD:EF:...\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/sign",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{signature_id}}",
								"sign"
							]
						},
						"description": "Complete signature using a digital certificate (Qualified Electronic Signature).\n\n**Required for certificate signatures:**\n- signed_data_hash: Hash of the document data\n- digital_signature: Cryptographic signature\n- certificate_fingerprint: Certificate identifier"
					},
					"response": []
				},
				{
					"name": "Cancel Signature",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"reason\": \"Dados incorrectos. Nova assinatura sera solicitada. Incorrect data - new signature will be requested.\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/cancel",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{signature_id}}",
								"cancel"
							]
						},
						"description": "Cancel a pending signature request."
					},
					"response": []
				},
				{
					"name": "Resend OTP",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/resend_otp",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"signatures",
								"{{signature_id}}",
								"resend_otp"
							]
						},
						"description": "Resend the OTP code to the signatory's email/phone. Use this when the previous OTP expired or wasn't received."
					},
					"response": []
				},
				{
					"name": "Public Signature View (No Auth)",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/signatures/public/{{share_token}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"signatures",
								"public",
								"{{share_token}}"
							]
						},
						"description": "View signature details using a public share token. This endpoint does NOT require API authentication - it uses the share token for access.\n\n**Use cases:**\n- Third party signing via link\n- Viewing document summary before signing"
					},
					"response": []
				}
			],
			"description": "Electronic signature management for eCMR documents"
		},
		{
			"name": "Shares",
			"item": [
				{
					"name": "List All Shares",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares"
							]
						},
						"description": "List all shares for a document including active, expired, and revoked shares.\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"token\": \"abc123...\",\n      \"type\": \"carrier\",\n      \"url\": \"https://app.40pes.pt/ecmr/view/abc123...\",\n      \"recipient_email\": null,\n      \"expires_at\": \"2026-02-27T15:30:00Z\",\n      \"access_count\": 5,\n      \"last_accessed_at\": \"2026-01-28T10:15:00Z\",\n      \"revoked\": false,\n      \"active\": true,\n      \"created_at\": \"2026-01-28T09:00:00Z\"\n    }\n  ]\n}\n```"
					},
					"response": []
				},
				{
					"name": "List Active Shares",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares/active",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares",
								"active"
							]
						},
						"description": "List only active shares (non-expired, non-revoked) for a document.\n\nUseful for checking which share links are currently valid."
					},
					"response": []
				},
				{
					"name": "Get Share Details",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares/{{share_token}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares",
								"{{share_token}}"
							]
						},
						"description": "Get detailed information about a specific share.\n\n**URL Parameters:**\n- `share_token`: The token returned when the share was created\n\n**Response includes:**\n- `url`: The public URL to access the document\n- `access_count`: Number of times the link was accessed\n- `last_accessed_at`: When the link was last used\n- `active`: Whether the share is currently valid"
					},
					"response": []
				},
				{
					"name": "Create Share (Carrier Access)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"share\": {\n    \"permissions\": \"carrier\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares"
							]
						},
						"description": "## Create Share with Carrier Permissions\n\nCreates a share URL that allows the user to act as the **Carrier**.\n\n**Use Case:** TMS needs to provide a URL to an operator who can assign/replace the driver in the field.\n\n**Carrier Capabilities:**\n- View document details\n- Assign or replace driver\n- Request signatures from other parties\n- Add transport observations\n\n---\n\n**Request Body:**\n```json\n{\n  \"share\": {\n    \"permissions\": \"carrier\"\n  }\n}\n```\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"token\": \"Kj3mN9pQ...\",\n    \"type\": \"carrier\",\n    \"url\": \"https://app.40pes.pt/ecmr/view/Kj3mN9pQ...\",\n    \"expires_at\": \"2026-02-27T15:30:00Z\",\n    \"active\": true\n  }\n}\n```\n\nThe `url` field contains the link to share with the operator."
					},
					"response": []
				},
				{
					"name": "Create Share (View Only)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"share\": {\n    \"permissions\": \"view\"\n  }\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares"
							]
						},
						"description": "## Create Share with View-Only Permissions\n\nCreates a share URL that allows **read-only** access to the document.\n\n**Use Case:** Share document status with clients, partners, or stakeholders who only need to track the shipment.\n\n**View-Only Capabilities:**\n- View document details and status\n- See signature progress\n- Download PDF (when completed)\n\n**Cannot:**\n- Edit any information\n- Request signatures\n- Assign drivers\n\n---\n\n**Request Body:**\n```json\n{\n  \"share\": {\n    \"permissions\": \"view\"\n  }\n}\n```\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"token\": \"Xy9zAbc...\",\n    \"type\": \"view\",\n    \"url\": \"https://app.40pes.pt/ecmr/view/Xy9zAbc...\",\n    \"expires_at\": \"2026-02-27T15:30:00Z\",\n    \"active\": true\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Create Share (With Email Notification)",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"share\": {\n    \"permissions\": \"view\",\n    \"recipient_email\": \"cliente@empresa.com\",\n    \"expires_at\": \"2026-03-01T23:59:59Z\"\n  },\n  \"send_notification\": true\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares"
							]
						},
						"description": "## Create Share with Email Notification\n\nCreates a share and automatically sends an email to the recipient with the access link.\n\n**Use Case:** Automatically notify a client or partner about document access.\n\n---\n\n**Request Body:**\n```json\n{\n  \"share\": {\n    \"permissions\": \"view\",\n    \"recipient_email\": \"cliente@empresa.com\",\n    \"expires_at\": \"2026-03-01T23:59:59Z\"\n  },\n  \"send_notification\": true\n}\n```\n\n**Parameters:**\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `permissions` | No | Access level (default: `view`) |\n| `recipient_email` | No | Email for tracking purposes |\n| `expires_at` | No | Expiration date (default: 30 days) |\n| `send_notification` | No | Send email automatically (default: false) |\n\n**Available Permissions:**\n\n| Value | Can View | Can Edit | Can Assign Driver |\n|-------|----------|----------|-------------------|\n| `view` | Yes | No | No |\n| `carrier` | Yes | Yes* | Yes |\n| `consignor` | Yes | Yes* | No |\n| `consignee` | Yes | Yes* | No |\n| `driver` | Yes | No | No |\n\n*Edit depends on document state"
					},
					"response": []
				},
				{
					"name": "Generate QR Code",
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n  \"expires_in\": 48\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares/generate_qr",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares",
								"generate_qr"
							]
						},
						"description": "## Generate QR Code for Document\n\nGenerates a QR code that can be scanned to access the document. Useful for printing on physical documents or displaying on screens.\n\n**Use Case:** Print QR code on CMR paper copy, display on warehouse screens, or embed in mobile apps.\n\n---\n\n**Request Body:**\n```json\n{\n  \"expires_in\": 48\n}\n```\n\n**Parameters:**\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `expires_in` | No | Hours until expiration (default: 24) |\n\n---\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"share\": {\n      \"token\": \"Qr1Code...\",\n      \"type\": \"viewer\",\n      \"url\": \"https://app.40pes.pt/ecmr/view/Qr1Code...\",\n      \"expires_at\": \"2026-01-30T15:30:00Z\"\n    },\n    \"qr_code_url\": \"https://app.40pes.pt/ecmr/view/Qr1Code...\",\n    \"qr_code_svg\": \"<svg xmlns=...\",\n    \"qr_code_base64\": \"data:image/png;base64,iVBORw0...\"\n  }\n}\n```\n\n**Response Fields:**\n- `qr_code_url`: URL encoded in the QR code\n- `qr_code_svg`: SVG string for embedding in HTML\n- `qr_code_base64`: PNG image as data URL for direct use in `<img>` tags"
					},
					"response": []
				},
				{
					"name": "Revoke Share",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares/{{share_token}}/revoke",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"api",
								"v1",
								"ecmr",
								"documents",
								"{{cmr_number}}",
								"shares",
								"{{share_token}}",
								"revoke"
							]
						},
						"description": "## Revoke a Share\n\nInvalidates an active share. After revocation, the share link will no longer work.\n\n**Use Cases:**\n- Security breach: revoke access immediately\n- Employee left: revoke their access links\n- Wrong recipient: revoke and create new share\n\n---\n\n**URL Parameters:**\n- `share_token`: Token of the share to revoke\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"message\": \"Share revoked successfully\",\n    \"share_token\": \"abc123...\",\n    \"revoked_at\": \"2026-01-28T16:00:00Z\"\n  }\n}\n```\n\n**Note:** Revocation is permanent. To restore access, create a new share."
					},
					"response": []
				}
			],
			"description": "## Document Sharing API\n\nManage access to eCMR documents through shareable URLs.\n\n### Key Concepts\n\n**Shares** are access tokens that create URLs for viewing or interacting with documents. Each share has:\n- **Permissions**: What the user can do (view, carrier, consignor, etc.)\n- **Expiration**: When the link stops working\n- **Token**: Unique identifier in the URL\n\n### Permission Levels\n\n| Permission | Description | Typical Use |\n|------------|-------------|-------------|\n| `view` | Read-only access | Clients tracking shipment |\n| `carrier` | Full carrier access | Operators managing transport |\n| `consignor` | Consignor access | Sender tracking |\n| `consignee` | Consignee access | Receiver tracking |\n| `driver` | Driver view | Driver reference |\n\n### Common TMS Integration Patterns\n\n1. **Backoffice Operator Access**: Create share with `permissions: carrier` to allow driver assignment\n2. **Client Status Tracking**: Create share with `permissions: view` for read-only access\n3. **QR Code for Documents**: Use `generate_qr` endpoint for printable codes"
		},
		{
			"name": "Error Codes Reference",
			"item": [
				{
					"name": "Authentication Errors (AUTH_*)",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/profile",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "tenant", "profile"]
						},
						"description": "## Authentication Error Codes\n\nThese errors occur during API authentication.\n\n### Tenant API Authentication\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `AUTH_NO_CREDENTIALS` | 401 | No API key or JWT token provided |\n| `AUTH_INVALID_API_KEY` | 401 | The API key is invalid or not found |\n| `AUTH_INVALID_JWT` | 401 | The JWT token is invalid |\n| `AUTH_JWT_DECODE_ERROR` | 401 | Failed to decode JWT token |\n| `AUTH_JWT_EXPIRED` | 401 | JWT token has expired |\n| `AUTH_TENANT_INACTIVE` | 401 | Tenant account is inactive |\n| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests, rate limit exceeded |\n\n### Reseller API Authentication\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `AUTH_INVALID_MASTER_API_KEY` | 401 | The master API key is invalid or not found |\n| `AUTH_RESELLER_INACTIVE` | 401 | Reseller account is inactive |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"AUTH_INVALID_API_KEY\",\n    \"message\": \"Invalid API key\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Document Errors (DOCUMENT_*)",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "documents", "{{cmr_number}}"]
						},
						"description": "## Document Error Codes\n\nThese errors occur when working with eCMR documents.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `DOCUMENT_NOT_FOUND` | 404 | Document with specified CMR number not found |\n| `DOCUMENT_NOT_EDITABLE` | 422 | Document cannot be edited (already issued) |\n| `DOCUMENT_NOT_DELETABLE` | 422 | Document cannot be deleted (already issued) |\n| `DOCUMENT_VALIDATION_FAILED` | 422 | Document data validation failed |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"DOCUMENT_NOT_EDITABLE\",\n    \"message\": \"Cannot update document after it has been issued\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Lifecycle Errors (LIFECYCLE_*)",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/lifecycle/issue",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "documents", "{{cmr_number}}", "lifecycle", "issue"]
						},
						"description": "## Lifecycle Error Codes\n\nThese errors occur during document state transitions.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `LIFECYCLE_INVALID_STATE` | 422 | Document is not in the expected state |\n| `LIFECYCLE_INVALID_TRANSITION` | 422 | State transition not allowed |\n| `LIFECYCLE_INVALID_DOCUMENT_STATE` | 422 | Cannot request signatures on a document that is not issued or accepted |\n| `LIFECYCLE_ISSUE_FAILED` | 422 | Failed to issue document |\n| `LIFECYCLE_ACCEPT_FAILED` | 422 | Failed to accept document |\n| `LIFECYCLE_DELIVER_FAILED` | 422 | Failed to deliver document |\n| `LIFECYCLE_COMPLETE_FAILED` | 422 | Failed to complete document |\n| `LIFECYCLE_CANCEL_FAILED` | 422 | Failed to cancel document |\n| `LIFECYCLE_CANNOT_CANCEL_COMPLETED` | 422 | Cannot cancel a completed document |\n| `LIFECYCLE_SIGNATURE_REQUIRED` | 422 | Required signature missing before transition |\n| `LIFECYCLE_SIGNATURES_INCOMPLETE` | 422 | Not all required signatures are complete |\n| `LIFECYCLE_ALREADY_SIGNED` | 422 | This role has already signed |\n| `LIFECYCLE_SIGNATURE_PENDING` | 422 | A signature request is already pending |\n| `LIFECYCLE_GOODS_INCOMPLETE` | 422 | Goods data is incomplete, cannot request signature |\n| `LIFECYCLE_OTP_FAILED` | 422 | Failed to send signature request OTP |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"LIFECYCLE_SIGNATURE_REQUIRED\",\n    \"message\": \"Carrier signature is required before this transition\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Signature Errors (SIGNATURE_*)",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/sign",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "documents", "{{cmr_number}}", "signatures", "{{signature_id}}", "sign"]
						},
						"description": "## Signature Error Codes\n\nThese errors occur during signature operations.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `SIGNATURE_NOT_FOUND` | 404 | Signature not found |\n| `SIGNATURE_ALREADY_COMPLETED` | 422 | Signature has already been completed |\n| `SIGNATURE_FAILED` | 422 | Signature failed and cannot be retried |\n| `SIGNATURE_EXPIRED` | 422 | Signature request has expired |\n| `SIGNATURE_CANCELLED` | 422 | Signature was cancelled |\n| `SIGNATURE_TYPE_INVALID` | 422 | Invalid signature type for this operation |\n| `SIGNATURE_TYPE_UNKNOWN` | 400 | Unknown signature type |\n| `SIGNATURE_OTP_REQUIRED` | 422 | OTP must be validated before signing |\n| `INVALID_ROLE_FOR_WITHOUT_SIGNATURE` | 422 | without_signature type only allowed for consignor or consignee |\n| `GEOLOCATION_REQUIRED` | 422 | Geolocation is required for without_signature type |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SIGNATURE_ALREADY_COMPLETED\",\n    \"message\": \"Signature already completed\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "OTP Errors (OTP_*)",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/validate_otp",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "documents", "{{cmr_number}}", "signatures", "{{signature_id}}", "validate_otp"]
						},
						"description": "## OTP Error Codes\n\nThese errors occur during OTP (One-Time Password) validation.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `OTP_EXPIRED` | 422 | OTP code has expired (15 min validity) |\n| `OTP_INVALID` | 422 | OTP code is incorrect |\n| `OTP_MAX_ATTEMPTS` | 422 | Maximum OTP attempts exceeded (3 attempts) |\n| `OTP_ALREADY_VALIDATED` | 422 | OTP has already been validated |\n| `OTP_BLOCKED` | 422 | Too many OTP attempts, signature is blocked |\n| `OTP_NO_CONTACT` | 422 | No email or phone to send OTP |\n| `OTP_EMAIL_FAILED` | 422 | Failed to send OTP via email |\n| `OTP_SMS_FAILED` | 422 | Failed to send OTP via SMS |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"OTP_EXPIRED\",\n    \"message\": \"OTP has expired. Please request a new one.\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Biometrics Errors (BIOMETRICS_*)",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/signatures/{{signature_id}}/sign",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "documents", "{{cmr_number}}", "signatures", "{{signature_id}}", "sign"]
						},
						"description": "## Biometrics Error Codes\n\nThese errors occur during biometric signature validation.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `BIOMETRICS_INVALID` | 422 | Biometric data validation failed |\n| `BIOMETRICS_INVALID_FORMAT` | 422 | Invalid JSON format for biometric data |\n| `BIOMETRICS_MISSING_FIELDS` | 422 | Required biometric fields missing |\n| `BIOMETRICS_INVALID_STROKES` | 422 | Strokes array is invalid |\n| `BIOMETRICS_NO_STROKES` | 422 | No strokes provided |\n| `BIOMETRICS_STROKE_INVALID` | 422 | Stroke missing points array |\n| `BIOMETRICS_STROKE_TOO_SHORT` | 422 | Stroke has too few points |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"BIOMETRICS_STROKE_TOO_SHORT\",\n    \"message\": \"Stroke 0 has too few points\",\n    \"details\": []\n  }\n}\n```\n\n**Required Biometric Data Structure:**\n```json\n{\n  \"strokes\": [{\"points\": [{\"x\": 0, \"y\": 0, \"t\": 0}]}],\n  \"stroke_count\": 1,\n  \"total_time\": 1000,\n  \"average_speed\": 100,\n  \"average_pressure\": 0.5\n}\n```"
					},
					"response": []
				},
				{
					"name": "Share Errors (SHARE_*)",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents/{{cmr_number}}/shares",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "documents", "{{cmr_number}}", "shares"]
						},
						"description": "## Share Error Codes\n\nThese errors occur when working with document shares.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `SHARE_NOT_FOUND` | 404 | Share link not found |\n| `SHARE_EXPIRED` | 410 | Share link has expired or been revoked |\n| `SHARE_CREATE_FAILED` | 422 | Failed to create share link |\n| `SMS_SEND_FAILED` | 422 | Failed to send driver SMS with share link |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SHARE_EXPIRED\",\n    \"message\": \"Share link has expired or been revoked\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Webhook Errors (WEBHOOK_*)",
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/tenant/webhook/test",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "tenant", "webhook", "test"]
						},
						"description": "## Webhook Error Codes\n\nThese errors occur when configuring or testing webhooks.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `WEBHOOK_NOT_CONFIGURED` | 400 | No webhook URL configured |\n| `WEBHOOK_UPDATE_FAILED` | 422 | Failed to update webhook configuration |\n| `WEBHOOK_UNREACHABLE` | 502 | Cannot reach webhook endpoint |\n| `WEBHOOK_INVALID_URL` | 400 | Invalid webhook URL format |\n| `WEBHOOK_SIGNATURE_ERROR` | 500 | Error generating webhook signature |\n| `WEBHOOK_SERIALIZATION_ERROR` | 500 | Error serializing webhook payload |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"WEBHOOK_UNREACHABLE\",\n    \"message\": \"Failed to reach webhook endpoint\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Signup & Verification Errors",
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/signup",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "signup"]
						},
						"description": "## Signup & Verification Error Codes\n\nThese errors occur during account registration and verification.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `SIGNUP_FAILED` | 422 | Account registration failed |\n| `EMAIL_REQUIRED` | 400 | Email address is required |\n| `VERIFICATION_NOT_FOUND` | 404 | No pending verification for this email |\n| `VERIFICATION_TOKEN_REQUIRED` | 400 | Verification token is required |\n| `VERIFICATION_TOKEN_INVALID` | 404 | Verification token is invalid |\n| `VERIFICATION_TOKEN_EXPIRED` | 410 | Verification token has expired (24h) |\n| `VERIFICATION_FAILED` | 422 | Email verification failed |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"VERIFICATION_TOKEN_EXPIRED\",\n    \"message\": \"Verification token has expired\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Reseller Errors (RESELLER_*, TENANT_*)",
					"request": {
						"auth": {
							"type": "apikey",
							"apikey": [
								{
									"key": "key",
									"value": "X-Master-API-Key",
									"type": "string"
								},
								{
									"key": "value",
									"value": "{{master_api_key}}",
									"type": "string"
								},
								{
									"key": "in",
									"value": "header",
									"type": "string"
								}
							]
						},
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/reseller/tenants",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "reseller", "tenants"]
						},
						"description": "## Reseller Error Codes\n\nThese errors occur when using the Reseller API.\n\n### Reseller Signup & Profile\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `RESELLER_SIGNUP_FAILED` | 422 | Reseller registration failed |\n| `RESELLER_UPDATE_FAILED` | 422 | Failed to update reseller profile |\n\n### Sub-Tenant Management\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `TENANT_CREATION_FAILED` | 422 | Failed to create sub-tenant |\n| `REGENERATE_KEY_FAILED` | 422 | Failed to regenerate sub-tenant API key |\n| `TENANT_ALREADY_SUSPENDED` | 422 | Tenant is already suspended |\n| `TENANT_ALREADY_ACTIVE` | 422 | Tenant is already active |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"TENANT_CREATION_FAILED\",\n    \"message\": \"A tenant with this VAT number already exists\",\n    \"details\": []\n  }\n}\n```"
					},
					"response": []
				},
				{
					"name": "Generic Errors",
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/api/v1/ecmr/documents",
							"host": ["{{base_url}}"],
							"path": ["api", "v1", "ecmr", "documents"]
						},
						"description": "## Generic Error Codes\n\nThese are general-purpose error codes used across the API.\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `VALIDATION_FAILED` | 422 | Data validation failed |\n| `RESOURCE_NOT_FOUND` | 404 | Requested resource not found |\n| `INVALID_ARGUMENT` | 400 | Invalid argument provided |\n| `INVALID_LOCALE` | 400 | Invalid locale code |\n| `INVALID_ROLE` | 400 | Invalid role specified (for PDF as-signed) |\n| `SEARCH_QUERY_REQUIRED` | 400 | Search query parameter required |\n| `INTERNAL_ERROR` | 500 | Internal server error |\n| `TENANT_UPDATE_FAILED` | 422 | Failed to update tenant profile |\n| `PDF_GENERATION_FAILED` | 422 | Failed to generate PDF |\n| `PDF_INVALID_DATA` | 422 | Invalid data for PDF generation |\n| `CERTIFICATE_ERROR` | 422 | Digital certificate error |\n\n**Example Error Response:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"VALIDATION_FAILED\",\n    \"message\": \"Validation failed\",\n    \"details\": [\"Carrier name is required\", \"Goods description is required\"]\n  }\n}\n```\n\n**Handling Error Codes in Your Application:**\n```javascript\nconst errorMessages = {\n  pt: {\n    OTP_EXPIRED: 'O código OTP expirou. Solicite um novo.',\n    OTP_INVALID: 'Código OTP inválido.',\n    SIGNATURE_ALREADY_COMPLETED: 'Esta assinatura já foi completada.',\n    // ... more translations\n  },\n  en: {\n    OTP_EXPIRED: 'OTP code has expired. Please request a new one.',\n    OTP_INVALID: 'Invalid OTP code.',\n    SIGNATURE_ALREADY_COMPLETED: 'This signature has already been completed.',\n    // ... more translations\n  }\n};\n\nfunction handleApiError(response) {\n  const code = response.error?.code;\n  const locale = getUserLocale();\n  return errorMessages[locale]?.[code] || response.error.message;\n}\n```"
					},
					"response": []
				}
			],
			"description": "Complete reference of all error codes returned by the API.\n\nAll error responses follow this structure:\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ERROR_CODE\",\n    \"message\": \"Human-readable message in English\",\n    \"details\": []\n  },\n  \"meta\": {\n    \"timestamp\": \"2025-01-15T12:00:00Z\"\n  }\n}\n```\n\n**Using Error Codes for i18n:**\nThe `code` field is machine-readable and stable. Use it to map to localized error messages in your application instead of displaying the English `message` to end users.\n\n**Error Categories:**\n- AUTH_* - Authentication errors (tenant and reseller)\n- DOCUMENT_* - Document errors\n- LIFECYCLE_* - State transition errors\n- SIGNATURE_* - Signature errors\n- OTP_* - OTP validation errors\n- BIOMETRICS_* - Biometric data errors\n- SHARE_* - Document sharing errors\n- WEBHOOK_* - Webhook configuration errors\n- VERIFICATION_* - Email verification errors\n- RESELLER_* - Reseller API errors\n- TENANT_* - Sub-tenant management errors\n- Generic codes - General errors"
		}
	],
	"auth": {
		"type": "apikey",
		"apikey": [
			{
				"key": "key",
				"value": "X-API-Key",
				"type": "string"
			},
			{
				"key": "value",
				"value": "{{api_key}}",
				"type": "string"
			},
			{
				"key": "in",
				"value": "header",
				"type": "string"
			}
		]
	},
	"event": [
		{
			"listen": "prerequest",
			"script": {
				"type": "text/javascript",
				"packages": {},
				"requests": {},
				"exec": [
					""
				]
			}
		},
		{
			"listen": "test",
			"script": {
				"type": "text/javascript",
				"packages": {},
				"requests": {},
				"exec": [
					""
				]
			}
		}
	],
	"variable": [
		{
			"key": "base_url",
			"value": "https://ecmr.40pes.pt"
		},
		{
			"key": "api_key",
			"value": ""
		},
		{
			"key": "tenant_id",
			"value": ""
		},
		{
			"key": "verification_token",
			"value": ""
		},
		{
			"key": "cmr_number",
			"value": ""
		},
		{
			"key": "signature_id",
			"value": ""
		},
		{
			"key": "consignor_signature_id",
			"value": ""
		},
		{
			"key": "carrier_signature_id",
			"value": ""
		},
		{
			"key": "consignee_signature_id",
			"value": ""
		},
		{
			"key": "share_token",
			"value": ""
		},
		{
			"key": "consignor_share_token",
			"value": ""
		},
		{
			"key": "carrier_share_token",
			"value": ""
		},
		{
			"key": "consignee_share_token",
			"value": ""
		},
		{
			"key": "signup_email",
			"value": ""
		},
		{
			"key": "master_api_key",
			"value": "",
			"description": "Reseller master API key (rk_live_xxx or rk_test_xxx)"
		},
		{
			"key": "reseller_id",
			"value": "",
			"description": "Reseller public ID (rsl_xxx)"
		},
		{
			"key": "reseller_verification_token",
			"value": "",
			"description": "Token from reseller verification email"
		},
		{
			"key": "reseller_signup_email",
			"value": ""
		},
		{
			"key": "created_tenant_id",
			"value": "",
			"description": "ID of the last sub-tenant created by reseller"
		},
		{
			"key": "created_tenant_api_key",
			"value": "",
			"description": "API key of the last sub-tenant created by reseller"
		}
	]
}
