Roles and permissions
Two things decide what you can do: the kind of account you have, and the role you hold on each company. A role is held on an entity — a company — not on an account. The same person can be an Admin on one company and a Viewer on another. That role decides what they can do in the E-Invoice application, and it is also what decides what an OAuth app they own can do through the API. This page covers both.
Account types
| Ordinary account | Reseller account | Existing account with reseller access | |
|---|---|---|---|
| Who it is for | Companies using the E-Invoice application, and partners and integrators using the OAuth API | Resellers who bring clients to Tax Star and nothing else | Someone who already uses E-Invoice and also resells |
| How you get it | Sign up, FTA onboarding, or an invitation to a company | Ask Tax Star by email; a Tax Star admin creates it | Ask Tax Star by email; a Tax Star admin switches reseller access on for your account |
| Passwords | One | One | Two: your E-Invoice password, and a separate reseller password Tax Star gives you |
| Company roles | Admin, Editor, Approver or Viewer on each company | None — it holds no company roles | The ones you already hold, unchanged |
| E-Invoice application | Yes | No | Yes, with your E-Invoice password |
| Reseller dashboard | No | Yes | Yes, with the reseller password |
| What its OAuth apps can call | The OAuth API, by your role on each company | The reseller endpoints and GET /oauth/me only | The OAuth API by role, plus the reseller endpoints |
Almost everyone has an ordinary account, and everything below — the four roles and what they allow — is about it. A reseller account holds no company roles: what it can do is on Reseller accounts. Reseller access on an existing account changes nothing below: you keep your companies and your roles, and gain the reseller side on top.
Tax Star staff approve every OAuth app before it can get a token, and are the only ones who create reseller accounts or switch reseller access on or off. Neither can be done by sign-up.
The four company roles
| Role | What it is |
|---|---|
| Admin | The person who created the entity — on production, whoever onboarded the company through the FTA. Full control, and the only role that can delete the entity or change or remove another Admin. |
| Editor | Runs the entity day to day — connection, mapping, tax codes, invoices, people — with two exceptions: cannot delete the entity, and cannot change or remove an Admin. |
| Approver | Decides invoices: approve, reject, comment. Changes nothing else. Needs no TaxStar account — approval requests arrive by email. |
| Viewer | Read-only. Sees the entity, its invoices and its settings, and changes none of it. |
Creating an entity makes you its Admin. Every other role arrives by invitation from an Admin or Editor of the entity, and is held on that entity only.
In the application
| Action on the entity | Admin | Editor | Approver | Viewer |
|---|---|---|---|---|
| See the entity, its invoices, reports, mapping and settings | Yes | Yes | Yes | Yes |
| Approve, reject or comment on an invoice | Yes | Yes | Yes | No |
| Edit entity details and TRN | Yes | Yes | No | No |
| Connect or disconnect the accounting system | Yes | Yes | No | No |
| Change PINT Mapping, tax codes and self-billing | Yes | Yes | No | No |
| Send, validate, email, upload or resubmit invoices | Yes | Yes | No | No |
| Fill in and submit a staged invoice | Yes | Yes | No | No |
| Turn invoice approval on or off | Yes | Yes | No | No |
| See who has access, and who has been invited | Yes | Yes | No | No |
| Invite an Editor, Approver or Viewer | Yes | Yes | No | No |
| Change someone's role, or remove them | Yes | Yes | No | No |
| Change or remove an Admin | Yes | No | No | No |
| Delete the entity | Yes | No | No | No |
An Editor does everything an Admin does day to day, seeing, inviting and removing people included, but can never change or remove an Admin, or delete the entity. That is what stops control of an entity being handed on, or taken away, by someone who was only given access to it. Approvers and Viewers do not see who else has access, or who has been invited.
The rules are checked on every request, not only on the buttons. Where your role does not allow something the control is still shown, switched off, with a note naming the role that can. The Roles & Permissions card on each entity's details page shows your own role and this table for that entity.
Inviting people
- An Admin or Editor invites someone by email on the entity details page and picks a role — Editor, Approver or Viewer. An app owned by an Admin or Editor can send the same invitation with POST /oauth/entities/{entity_id}/members.
- The invitation link is valid for 24 hours.
- Editor or Viewer: with an account, they sign in with the invited email address, then open the link. Without one, the link opens a confirmation page and Accept & create account creates it, emailing a temporary password. The invitation is tied to that address. An account made this way can be invited to other companies like any other, but cannot create a company of its own until its holder onboards one through the FTA — see Users and roles.
- Approver: no account needed. The link opens a confirmation page, and pressing Accept invitation is the whole step.
- Until they accept, they are listed as invited and see nothing of the entity.
An Approver's invitation is accepted by the button, never by opening the link. Mail security scanners open every link in a message before a person does; if opening it counted, every Approver would be signed up the moment the email arrived.
A role can be changed, or access removed, from the same place. Both take effect on the next request — including for an OAuth app, and for approval links already sent.
Approving by email, without an account
When an entity requires approval, each invoice waiting on it sends every Approver an email with their own secure link. If the entity has no Approvers, the owner and Admins are asked instead; Editors and Viewers are never emailed. The link opens the invoice, and the Approver can approve, reject or leave a comment there — the same decision, with the same effect, as Invoices to Approve in the dashboard.
| On the approval page | |
|---|---|
| Shown | Invoice number, dates, the counterparty's name, every line (description, quantity, unit price, tax, amount), subtotal, tax and total, and any validation errors. |
| Not shown | The counterparty's email, phone and address, the buyer's TRN, and the names of whoever commented. Those stay behind the sign-in. |
A link stops working when any of these happens:
- the invoice is decided, by anyone — each Approver's copy closes together;
- 7 days pass;
- the person it was sent to is removed from the entity, or made a Viewer.
Each link is issued to one person and records them as the one who decided, so it should not be forwarded. An invoice that failed validation reaches the Approver too, with its errors listed; it can be rejected or commented on, but not approved until it passes.
Invoices pushed through the API
Require Approval for Sending holds every invoice the entity sends from the dashboard or a connected accounting system. An invoice pushed through the API decides for itself, with bypass_send_approval on POST /oauth/invoices. It defaults to true: the invoice is sent without waiting, even while the entity requires approval.
| When | What happens |
|---|---|
| Approval off | Sent. bypass_send_approval makes no difference. |
| Approval on, bypass_send_approval absent or true | Sent without waiting. Approvers are not emailed, and it never appears under Invoices to Approve. |
| Approval on, bypass_send_approval false | Held as WAITING_FOR_APPROVAL. Approvers are emailed and decide it exactly as described above. |
Every PATCH decides again, with the same default — so a rejected invoice that is corrected and resubmitted without the option is sent; send false to have it approved again. In a bulk push, each invoice decides for itself.
Approval is never a way round validation. An invalid invoice is refused with 422 and nothing is stored, whatever the option says. An invoice that bypasses approval and later fails the check just before sending is not put in front of the Approvers either; it shows as VALIDATION_FAILED for the integration to fix.
An integration that relied on approval for its invoices before this option existed sends "bypass_send_approval": false to keep them waiting.
In the OAuth API
An OAuth app acts for the person who owns it. It reaches the entities that person can reach, with the role they hold on each:
| How the app reaches the entity | Role it acts with |
|---|---|
| Created through the app | Admin (via: app). Entities made with POST /oauth/entities, including ones made for the app's own users. |
| Owned by the app's owner | Admin (via: owner). Every entity the owner created in the E-Invoice application — reachable the moment the app is approved. |
| Shared with the app's owner | The role the owner holds there (via: member). An Editor invitation gives the app editor access; an Approver or Viewer invitation gives it read-only access. |
| API call | Admin | Editor | Approver | Viewer |
|---|---|---|---|---|
| GET /oauth/entities, GET /oauth/entities/{id} | Yes | Yes | Yes | Yes |
| See users_access (who has access) on those entities | Yes | Yes | No | No |
| GET /oauth/invoices/sent, /oauth/invoices/received and their status | Yes | Yes | Yes | Yes |
| PATCH /oauth/entities/{id} | Yes | Yes | No | No |
| POST /oauth/invoices/validate | Yes | Yes | No | No |
| POST /oauth/invoices, POST /oauth/invoices/bulk, PATCH /oauth/invoices/{id} | Yes | Yes | No | No |
| GET and POST /oauth/entities/{id}/members, DELETE .../members/invitations/{id} (invite an Editor, Approver or Viewer) | Yes | Yes | No | No |
| DELETE /oauth/entities/{id} | Yes | No | No | No |
So an Editor's app can read the entity, update it, and validate, send and update invoices from it — everything an Editor does — except delete the entity.
A Viewer's app can only view: it lists and opens the entity, its sent and received invoices and their status, and every call that would change something answers 403. The sent list covers every invoice sent through the API for the entity, not only the app's own — otherwise an app that cannot send would have nothing to see. Each invoice carries sent_by_this_app, and another app's identifiers are left out. An Approver's app is read-only in the same way: there is no approval endpoint in the API, and approval is done by a person, in the dashboard or from the emailed link. Whether an invoice the app pushes waits for that approval at all is decided per invoice — Invoices pushed through the API.
Only invoices your own app sent can be changed with PATCH, whatever your role.
People follow the application's rules too. The API has no endpoints for inviting people, changing their roles or removing them — an Admin or an Editor does that on the entity details page in the application. What the API does return is who already has access: each entity's users_access lists the members for an Admin's or an Editor's app, and comes back empty for an Approver's or a Viewer's app, who do not see who else has access in the application either. Pending invitations are not returned by the API at all.
POST /oauth/entities follows the account, not a role. On production it answers 403 for everyone, because every entity comes from FTA onboarding. On the development server it answers 403 for an account that was created by accepting an invitation; that account's app still reaches every entity the account was invited to, with the role it holds there.
Every entity in GET /oauth/entities says which case it is, so an integration can decide what to offer before it calls:
{
"entities": [
{
"_id": "66f1c0ffee...",
"company_name": "ABC Corporation",
"trn": "100000000000003",
"access": {
"role": "editor",
"via": "member",
"can_write": true,
"can_delete": false
}
}
]
}Nothing to connect
There is no connect step. An entity is usable through the API as soon as your app is approved, because the app reaches every entity you own or are a member of — and stops reaching it when your role there ends.
To see the list, sign in and open Entities this app can access on any of your apps under Your apps: each company, its entity_id, your role and what the app may do there. From your integration, GET /oauth/entities returns the same list to the app's own token.
Webhooks follow the same rules. invoice.received goes to every app that can read the receiving entity. Events about a sent invoice go to the app that sent it.
Access is checked on every call
Nothing about entity access is stored in the access token. Membership is read on each request, so removing the app's owner from an entity, or demoting them, changes what the app can do on its very next call. The same applies to invoices: the app lists and reads sent and received invoices only for entities it can still reach.
| Response | Meaning |
|---|---|
| 404 Entity not found | The app cannot reach the entity at all — or it does not exist. The two are answered the same on purpose, so the API never confirms an id you have no access to. |
| 403 read-only | The app can see the entity, but the owner is an Approver or Viewer there, and the call changes something. |
| 403 only an admin can delete | DELETE /oauth/entities/{id} from an app whose owner is an Editor. Everything else an Editor may do still works. |
Users your app creates
Users made with POST /oauth/users belong to the app. Entities created for them with user_id are owned by that user and reached by the app as an Admin (via: app). They are separate from people invited to an entity in the application, who hold the roles above.
Related
Resellers are on Reseller accounts. The dashboard walk-through of each role is on Users and roles. Approval in the sending flow is on Sending invoices. Creating an OAuth app is on Create an app, managing it on Your apps, and the entity endpoints are on Entities.