A series by scenario
Why this page exists
Section titled “Why this page exists”Inbound documents — the invoices somebody else sends to you — are delivered in real life by the tax authority. On the sandbox server we never talk to them: it is a server for trial runs, and nothing on it reaches a real institution.
The consequence is that your organisation there is empty. GET inbound returns a list with no
entries, there is no document to fetch, and no document to decide on. So the entire inbound
direction cannot be written or tried.
The endpoint described on this page fixes that: with one request it fills your organisation with a series of inbound invoices, one for every case your software has to survive.
Scenario catalogue
Section titled “Scenario catalogue”This is the list of cases the series creates. Every scenario has a name, and those names are stable — they do not change between releases, so you can write them into your test.
The three you cannot create yourself
Section titled “The three you cannot create yourself”If you read only one section of this page, read this one.
| Scenario name | What state the document is in | What your software gets when it sends a decision |
|---|---|---|
deadlinePassed | the decision deadline has passed, so the tax authority has already accepted the document itself | 409 with code EARH-3006 |
alreadyAccepted | a decision has already been made and confirmed — the document is accepted | 409 with the same code |
alreadyRejected | the same, but the document is rejected | 409 with the same code |
⛔ These three states do not come about through a request. They come about through the PASSAGE OF TIME, or through an action that has already happened. That is why you cannot produce them through placing a single document either, which always creates a document in its initial state.
It is also why software that has not met them in a trial run meets them first in production — at a real customer, on a real invoice.
What content the document arrives with
Section titled “What content the document arrives with”| Scenario name | What the document carries |
|---|---|
full | both machine-readable content (UJP JSON) and a PDF |
payloadOnly | machine-readable content only, no PDF |
pdfOnly | a PDF only |
noContent | ⛔ neither |
noContent is not an unfinished record. That is how a document looks when the privilege to
fetch its content is missing at the tax authority: the document exists, appears in the list, and can
be decided on — there is simply nothing to download.
📌 Which format returns content and which returns an error is described under Inbound documents → Downloading the content. That holds for every inbound document, not only for seeded ones.
Other document states
Section titled “Other document states”| Scenario name | What state the document is in |
|---|---|
acknowledged | receipt is already acknowledged, so the document is not returned when you ask for unfetched ones only; it carries an acknowledgement time |
deadlineToday | the decision deadline expires today — a boundary case, a decision still goes through |
Amounts
Section titled “Amounts”| Scenario name | What amount it carries |
|---|---|
zeroVat | VAT is zero |
creditNote | all amounts are negative |
largeAmount | an amount near the upper bound of the format |
For the filters when listing
Section titled “For the filters when listing”| Scenario name | What it lets you try |
|---|---|
secondSender | filtering by the sender’s tax number — this document carries a different one from all the rest |
olderThanWeek | filtering by arrival date, with by=created |
updatedRecently | fetching only what has changed, with by=updated |
The first request
Section titled “The first request”curl -X POST https://sandbox.api.earhiva.mk/api/integration/v1/sandbox/seed \ -H "X-Api-Key: <YOUR KEY>" \ -H "X-Software-Id: <NAME AND VERSION OF YOUR APPLICATION>" \ -H "Content-Type: application/json" \ -d '{ "seed": 1 }'The response lists the documents created. For each one it says which scenario it came from and what to expect of it — so your test can assert rather than guess:
{ "seed": 1, // the series number that was used "created": 15, // how many documents were created "deleted": 0, // how many older seeded documents were removed; 0 without clearing "documents": [ { "scenario": "full", "docUid": "eah_i_…", "euid": "SEED-1-full", "expect": "format=original and format=pdf return 200; format=ubl returns 404" }, { "scenario": "deadlinePassed", "docUid": "eah_i_…", "euid": "SEED-1-deadlinePassed", "expect": "POST decision returns 409 EARH-3006 — the deadline has passed" } // …and one entry for every other scenario ]}docUid is the document’s identifier on our side. You then use it with GET inbound/{docUid},
GET inbound/{docUid}/file and POST inbound/{docUid}/decision.
The fields of the request
Section titled “The fields of the request”The request body has three fields and none of them is required.
| Field | Type | What happens if you omit it |
|---|---|---|
seed | integer | 1 is used — not a random number |
reset | true/false | nothing is deleted |
scenarios | list of names | every scenario in the catalogue is created |
seed — the series number
Section titled “seed — the series number”The same number gives the same series. Same amounts, same dates, same senders, same deadlines, in the same order.
That is the only reason the number exists. Without it every fill would produce a different series, so a test that failed yesterday would pass today — not because anything was fixed, but because the data is different.
| What you send | What you get |
|---|---|
"seed": 1 | series number 1 |
"seed": 1 again | the same series number 1 |
"seed": 2 | a different series — if you need a second, parallel one |
| the field omitted | series number 1 |
reset — clearing before the fill
Section titled “reset — clearing before the fill”curl -X POST https://sandbox.api.earhiva.mk/api/integration/v1/sandbox/seed \ -H "X-Api-Key: <YOUR KEY>" \ -H "X-Software-Id: <NAME AND VERSION OF YOUR APPLICATION>" \ -H "Content-Type: application/json" \ -d '{ "seed": 1, "reset": true }'With reset: true the invoices this same endpoint created earlier are deleted — and nothing
else.
⛔ A document that arrived by another route is left alone. That includes an invoice you placed through one invoice with your own content: it carries content you supplied and you may have spent a long time assembling it.
This lets your test start from the same state every time, which is what running it automatically requires.
scenarios — only part of the catalogue
Section titled “scenarios — only part of the catalogue”When you are trying one case, you do not need the whole series:
curl -X POST https://sandbox.api.earhiva.mk/api/integration/v1/sandbox/seed \ -H "X-Api-Key: <YOUR KEY>" \ -H "X-Software-Id: <NAME AND VERSION OF YOUR APPLICATION>" \ -H "Content-Type: application/json" \ -d '{ "seed": 1, "reset": true, "scenarios": ["deadlinePassed", "alreadyAccepted"] }'If you omit the field, every scenario is created.
⛔ A name that is not in the catalogue is refused, and then nothing is created. The response
is 400 with code EARH-2030 and lists the allowed names. A typo will not
produce half a series — that is a state you would not expect and would not notice.
Use in an automated test
Section titled “Use in an automated test”The pattern we recommend for one cycle:
1. POST sandbox/seed { "seed": 1, "reset": true } → keep the response; it is the expected result for step 3
2. GET inbound fetch them all → assert that the number of documents returned matches the `created` field
3. For every document in the response from step 1: GET inbound/{docUid} GET inbound/{docUid}/file?format=original → 200 or 404, per the scenario POST inbound/{docUid}/decision → 200 or 409, per the scenario
4. Assert that no response is a 500Step 1 returns everything step 3 needs.
💡 Do not write the scenario list into your test as a fixed value — read it from the response. Your test then stays correct when we add a new scenario, and adding one is not a change to the contract.
Errors this endpoint returns
Section titled “Errors this endpoint returns”| Code | When it appears |
|---|---|
EARH-2030 · 400 | a name in scenarios that is not in the catalogue. Nothing is created; the response lists the allowed ones |
EARH-1008 · 400 | the X-Software-Id header is missing |
EARH-1009 · 404 | the endpoint was called on a server that is not the sandbox |
What this endpoint does NOT do
Section titled “What this endpoint does NOT do”| It creates inbound invoices only | the outbound direction is tried with a real POST outbound |
| It works only in your organisation | no call sees into or changes anyone else’s |
| Nothing leaves for the tax authority | neither on creation nor when you send a decision |
reset deletes only what was seeded | a document created another way stays |
| It does not accept content from you | that is one invoice with your own content |
Related
Section titled “Related”- One invoice with your own content — when you have a specific file, rather than a catalogue
- Inbound documents — what the statuses mean and how content is downloaded
- Error catalogue — every code the API can return
- Limits and rules — how many calls per minute you may make