{
  "info": {
    "_postman_id": "04b99d56-b5ab-4918-9526-75a4903303b5",
    "name": "SLTax360 API",
    "description": "Send your first invoice to SLTax360, step by step. The folders follow the ladder: 0 checks your key, 1 creates an invoice with only the six required fields, 2 previews a fuller invoice, 3 reads the reference lists, 4 reads the invoice back, attaches a document reference, and sends an endorsement and a cancellation on the same policy.\n\nBefore you start, set the collection variable `api_key` to the key we issued you. `base_url` is already set to `https://api.sltax360.com/api/v1`. Always use `https://`.\n\nPreview (folder 2) stores nothing, so you can try any body there. It is still logged and counts toward your hourly rate limit.\n\nA create (folders 1 and 4) is real. Each run makes new invoices, and running it again makes more. Ids such as `company_id` are different on every account: look up your own in folder 3.\n\nTransactions on the same policy (new, endorsement, cancellation) are linked by `policy_number`, so send the same `policy_number` for every transaction on a policy.\n\nA create does not calculate surplus lines tax. Send the tax and fees you billed in `fees[]` (for example `sl_tax` and `stamping_fee`), or use preview to work them out first.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.sltax360.com/api/v1",
      "type": "string"
    },
    {
      "key": "api_key",
      "value": "sltax_t2_replace_with_your_key",
      "type": "string"
    },
    {
      "key": "invoice_id",
      "value": "",
      "type": "string"
    },
    {
      "key": "doc_uuid",
      "value": "demo-doc-0001",
      "type": "string"
    },
    {
      "key": "policy_number",
      "value": "",
      "type": "string"
    },
    {
      "key": "policy_id",
      "value": "",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "0. Hello",
      "description": "Check that your key works before you do anything else.",
      "item": [
        {
          "name": "Check my key",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Response shows the key tier\", function () {",
                  "    pm.expect(pm.response.json().data.tier.code).to.be.a(\"string\");",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/auth/me",
              "host": ["{{base_url}}"],
              "path": ["auth", "me"]
            },
            "description": "Returns your key name, API tier, permissions and current rate limit; a 401 means the key is wrong."
          },
          "response": []
        }
      ]
    },
    {
      "name": "1. First invoice",
      "description": "Create a real invoice with only the six required fields. Each run creates a new invoice.",
      "item": [
        {
          "name": "Create an invoice (6 required fields)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 201\", function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "var body = pm.response.json();",
                  "pm.test(\"Response has data.id\", function () {",
                  "    pm.expect(body.data.id).to.be.a(\"number\");",
                  "});",
                  "if (body.data && body.data.id) {",
                  "    pm.collectionVariables.set(\"invoice_id\", body.data.id);",
                  "    pm.collectionVariables.set(\"policy_number\", body.data.policy_number);",
                  "    pm.collectionVariables.set(\"policy_id\", body.data.policy_id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"policy_number\": \"DEMO-{{$timestamp}}\",\n  \"insured_name\": \"Harbor Point Marine LLC\",\n  \"state_code\": \"TX\",\n  \"net_premium\": 12500.00,\n  \"effective_date\": \"2026-10-01\",\n  \"expiration_date\": \"2027-10-01\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/invoices",
              "host": ["{{base_url}}"],
              "path": ["invoices"]
            },
            "description": "Creates a real invoice from the six required fields, returns 201, and saves `data.id` and the policy number in the `invoice_id` and `policy_number` variables for folder 4."
          },
          "response": []
        }
      ]
    },
    {
      "name": "2. Send what you have",
      "description": "Preview a fuller invoice. Preview stores nothing, so you can change the body and send it as often as your rate limit allows.",
      "item": [
        {
          "name": "Preview an invoice with coverages, insurer, fees and address",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "var data = pm.response.json().data;",
                  "pm.test(\"Response has a tax calculation and a validation block\", function () {",
                  "    pm.expect(data).to.have.property(\"tax_calculation\");",
                  "    pm.expect(data.validation).to.have.property(\"errors\");",
                  "});",
                  "pm.test(\"No validation errors\", function () {",
                  "    pm.expect(data.validation.errors).to.have.lengthOf(0);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"policy_number\": \"DEMO-0001\",\n  \"insured_name\": \"Harbor Point Marine LLC\",\n  \"state_code\": \"TX\",\n  \"type_code\": \"NEW\",\n  \"net_premium\": 12500.00,\n  \"effective_date\": \"2026-10-01\",\n  \"expiration_date\": \"2027-10-01\",\n  \"coverages\": [\n    { \"code\": \"9334\", \"title\": \"GEN LIAB - PREMISES LIAB COMM\", \"amount\": 12500.00 }\n  ],\n  \"insurers\": [\n    { \"company_id\": 516, \"percent\": 100 }\n  ],\n  \"fees\": [\n    { \"type\": \"policy_fee_company\", \"amount\": 150.00 }\n  ],\n  \"insured_address\": {\n    \"line1\": \"100 Harbor Drive\",\n    \"city\": \"Galveston\",\n    \"zip\": \"77550\",\n    \"type_id\": 2\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/invoices/preview",
              "host": ["{{base_url}}"],
              "path": ["invoices", "preview"]
            },
            "description": "Returns the invoice as we read it, the tax calculation and a `validation` block, without storing anything; read `validation.errors` even on a 200, and note that preview ignores `insurers` (replace `company_id` with your own id from folder 3 before you create)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "3. Reference lists",
      "description": "Look up the codes and ids you can send. These lists change rarely, so fetch them once and cache them.",
      "item": [
        {
          "name": "States",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/reference/states",
              "host": ["{{base_url}}"],
              "path": ["reference", "states"]
            },
            "description": "Lists the states with their ids and the two-letter codes you send as `state_code`."
          },
          "response": []
        },
        {
          "name": "Lines of business",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/lobs",
              "host": ["{{base_url}}"],
              "path": ["lobs"]
            },
            "description": "Lists the lines of business on your account; send one of these ids as the optional `lob_id`."
          },
          "response": []
        },
        {
          "name": "Coverages",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/coverages",
              "host": ["{{base_url}}"],
              "path": ["coverages"]
            },
            "description": "Lists the coverage codes on your account, 100 per page (use `?page=2` for more); the list is the same for every state."
          },
          "response": []
        },
        {
          "name": "Fee types",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/reference/fee-types",
              "host": ["{{base_url}}"],
              "path": ["reference", "fee-types"]
            },
            "description": "Lists the codes you can send as `fees[].type`."
          },
          "response": []
        },
        {
          "name": "Document types",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/reference/document-types",
              "host": ["{{base_url}}"],
              "path": ["reference", "document-types"]
            },
            "description": "Lists the document type codes we recognise for `documents[].type`; a code we do not recognise is kept but is not sent to the state."
          },
          "response": []
        },
        {
          "name": "Invoice types",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/reference/invoice-types",
              "host": ["{{base_url}}"],
              "path": ["reference", "invoice-types"]
            },
            "description": "Lists our internal transaction types; these codes are not `type_code` values, so for `type_code` send exactly NEW, RENEWAL, ENDORSEMENT or CANCELLATION."
          },
          "response": []
        },
        {
          "name": "Search carriers",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/companies/search?q=lloyd",
              "host": ["{{base_url}}"],
              "path": ["companies", "search"],
              "query": [
                {
                  "key": "q",
                  "value": "lloyd",
                  "description": "Part of the carrier name or its NAIC code, at least 2 characters."
                }
              ]
            },
            "description": "Finds carriers by name or NAIC code; use the returned `id` as `company_id` in `insurers[]` or at the top level."
          },
          "response": []
        }
      ]
    },
    {
      "name": "4. Go further",
      "description": "Read your invoice back, attach a document reference, then send an endorsement and a cancellation on the same policy. Run folder 1 first, so `invoice_id` and `policy_number` are set. The endorsement and the cancellation are real invoices.",
      "item": [
        {
          "name": "Read the invoice back",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "pm.test(\"Invoice has a status\", function () {",
                  "    pm.expect(pm.response.json().data.status).to.be.a(\"string\");",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/invoices/{{invoice_id}}",
              "host": ["{{base_url}}"],
              "path": ["invoices", "{{invoice_id}}"]
            },
            "description": "Returns the invoice you created, including `status` (for example `new`) and `filed` (true once the filing has been sent)."
          },
          "response": []
        },
        {
          "name": "Attach a document reference",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 201 (new) or 200 (updated)\", function () {",
                  "    pm.expect(pm.response.code).to.be.oneOf([200, 201]);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"declaration_page\",\n  \"filename\": \"dec-page.pdf\",\n  \"mime_type\": \"application/pdf\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/invoices/{{invoice_id}}/documents/{{doc_uuid}}",
              "host": ["{{base_url}}"],
              "path": ["invoices", "{{invoice_id}}", "documents", "{{doc_uuid}}"]
            },
            "description": "Adds a reference to a document in your own system (no file bytes), keyed by your document id in the path; `type` is required, and sending it again is safe (201 the first time, 200 after)."
          },
          "response": []
        },
        {
          "name": "List the invoice documents",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 200\", function () {",
                  "    pm.response.to.have.status(200);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/invoices/{{invoice_id}}/documents",
              "host": ["{{base_url}}"],
              "path": ["invoices", "{{invoice_id}}", "documents"]
            },
            "description": "Lists the documents on the invoice with their `fetch_status`, which shows whether we have retrieved the file yet."
          },
          "response": []
        },
        {
          "name": "Endorsement (same policy_number)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 201\", function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "pm.test(\"Linked to the same policy as the first invoice\", function () {",
                  "    pm.expect(String(pm.response.json().data.policy_id)).to.eql(String(pm.collectionVariables.get(\"policy_id\")));",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"policy_number\": \"{{policy_number}}\",\n  \"insured_name\": \"Harbor Point Marine LLC\",\n  \"state_code\": \"TX\",\n  \"type_code\": \"ENDORSEMENT\",\n  \"net_premium\": 1200.00,\n  \"effective_date\": \"2027-01-15\",\n  \"expiration_date\": \"2027-10-01\",\n  \"coverages\": [\n    { \"code\": \"9334\", \"amount\": 1200.00 }\n  ],\n  \"insurers\": [\n    { \"company_id\": 167, \"percent\": 100 }\n  ],\n  \"fees\": [\n    { \"type\": \"sl_tax\", \"amount\": 58.20 },\n    { \"type\": \"stamping_fee\", \"amount\": 0.48 }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/invoices",
              "host": ["{{base_url}}"],
              "path": ["invoices"]
            },
            "description": "Creates a real endorsement invoice that adds premium to the policy from folder 1. Send the same policy_number as the original policy. Send the date the change takes effect as effective_date and the policy's expiration date as expiration_date. Today the stored policy record takes these dates. Amounts that return premium are negative. Every amount is the amount of the change, not the policy total. Use preview to work out the tax on the change; it accepts negative amounts. Replace company_id 167 with your own carrier id from Search carriers (folder 3)."
          },
          "response": []
        },
        {
          "name": "Cancellation (same policy_number)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Status is 201\", function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "pm.test(\"Linked to the same policy as the first invoice\", function () {",
                  "    pm.expect(String(pm.response.json().data.policy_id)).to.eql(String(pm.collectionVariables.get(\"policy_id\")));",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"policy_number\": \"{{policy_number}}\",\n  \"insured_name\": \"Harbor Point Marine LLC\",\n  \"state_code\": \"TX\",\n  \"type_code\": \"CANCELLATION\",\n  \"net_premium\": -6250.00,\n  \"effective_date\": \"2027-04-01\",\n  \"expiration_date\": \"2027-10-01\",\n  \"coverages\": [\n    { \"code\": \"9334\", \"amount\": -6250.00 }\n  ],\n  \"insurers\": [\n    { \"company_id\": 167, \"percent\": 100 }\n  ],\n  \"fees\": [\n    { \"type\": \"sl_tax\", \"amount\": -303.13 },\n    { \"type\": \"stamping_fee\", \"amount\": -2.50 }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/invoices",
              "host": ["{{base_url}}"],
              "path": ["invoices"]
            },
            "description": "Creates a real cancellation invoice that returns premium on the policy from folder 1. Send the same policy_number as the original policy. Send the date the change takes effect as effective_date and the policy's expiration date as expiration_date. Today the stored policy record takes these dates. Amounts that return premium are negative. Every amount is the amount of the change, not the policy total. Use preview to work out the tax on the change; it accepts negative amounts. Replace company_id 167 with your own carrier id from Search carriers (folder 3)."
          },
          "response": []
        }
      ]
    }
  ]
}
