Skip to content

Creating Documents

This guide walks through the process of creating sales and purchase documents via the API.


Overview

The following endpoints support document creation:

Endpoint Document Type
POST /invoices Sales invoices
POST /orders Sales orders
POST /receipts Receipts / payment confirmations
POST /purchases Purchase / supplier invoices
POST /purchase_orders Purchase orders
POST /transfer_orders Stock transfer orders

All document creation endpoints:

  • Require a session token (Authorization: Bearer <xa-token>)
  • Require a nonce query parameter
  • Accept a JSON request body
  • Return 201 Created on success with a documentCreated response
  • Optionally return a PDF when print=1 is passed

Step-by-step: Creating an Invoice

1. Prepare the request body

A customerDocument object. Required fields: document_set, seq_number, date, currency, total_amount.

{
  "document_set": "FT",
  "seq_number": "FT2024/1002",
  "date": "2024-11-15",
  "currency": "EUR",
  "net_amount": 1000.00,
  "vat": 230.00,
  "total_amount": 1230.00,
  "payment_type": "Transferência Bancária",
  "customer": {
    "name": "Acme Corp",
    "vat_id": "PT123456789",
    "billing_address": {
      "postal_address": "Rua da Liberdade 1",
      "city": "Lisboa",
      "zip_code": "1250-001",
      "country": "PT"
    }
  },
  "items": [
    {
      "item_code": "CONSULT",
      "description": "Consulting Services — November 2024",
      "qty": 2,
      "unit_price": 500.00,
      "vat": 23.0
    }
  ]
}

2. Send the request

POST /api/03101176/v4.0.0/invoices?nonce=1700000000001
Authorization: Bearer <xa-token>
Content-Type: application/json

{ ... document body ... }

3. Handle the response

On 201 Created:

{
  "id": 1002,
  "documentSeries": "FT",
  "documentNumber": "FT2024/1002",
  "url": "https://gestix.pt/..."
}

On 400 Bad Request — check the apiError for the specific field causing the issue.

On 409 Conflict — a document with this document_set + seq_number already exists.


Getting a PDF

Pass print=1 to receive the PDF of the created document directly in the response body:

POST /api/03101176/v4.0.0/invoices?nonce=1700000000002&print=1
Authorization: Bearer <xa-token>
Content-Type: application/json

The response will have Content-Type: application/pdf and contain the PDF binary.

response = requests.post(url, params={"nonce": nonce, "print": 1}, ...)
if response.headers["Content-Type"] == "application/pdf":
    with open("invoice.pdf", "wb") as f:
        f.write(response.content)

Document Lines (items)

Each line item in the items array is a documentLine:

{
  "item_code": "WIDGET-A",
  "description": "Widget Type A",
  "qty": 10,
  "unit_price": 25.00,
  "discount": 5.0,
  "vat": 23.0,
  "vat_included": false
}
  • description is required
  • item_code is optional but links the line to a product in /articles
  • When vat_included is true, unit_price is treated as a gross (VAT-inclusive) price

Notes on Required Fields

Field Notes
document_set Must match a document set configured in Gestix
seq_number Must be unique within its document_set
date Format: YYYY-MM-DD
currency Must be a valid currency code (e.g., EUR)
total_amount Must match the sum of line totals (server may validate)

Creating Supplier Documents

The process is identical for POST /purchases and POST /purchase_orders, but the request body uses a supplierDocument schema — note the slight field name differences (related_doc vs related_document, source_warehouse instead of warehouse).


Example in Python

import requests
import time

BASE_URL = "https://gestix.pt:443/api/03101176/v4.0.0"
TOKEN = "your-session-token"

document = {
    "document_set": "FT",
    "seq_number": "FT2024/1003",
    "date": "2024-11-15",
    "currency": "EUR",
    "total_amount": 246.00,
    "customer": {"name": "Test Customer"},
    "items": [
        {
            "description": "Test Item",
            "qty": 1,
            "unit_price": 200.00,
            "vat": 23.0
        }
    ]
}

nonce = int(time.time() * 1000)

response = requests.post(
    f"{BASE_URL}/invoices",
    params={"nonce": nonce},
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json"
    },
    json=document
)

if response.status_code == 201:
    result = response.json()
    print(f"Invoice created: {result['documentNumber']} (id={result['id']})")
else:
    error = response.json()
    print(f"Error: {error['code']}{error['message']}")