Folio API

Overview
  1. Technology
  2. Getting started
  3. Core concepts
  4. Examples

Reference
  1. Query
  2. Mutation
  3. Subscription
  4. Scalars
  5. Objects
  6. Enums
  7. Interfaces

Schema

Overview

Caveat: The API is not publicly available yet, but it's possible to request access by contacting support at hei@folio.no.

If you already have access, go to the playground to experiment with queries.

The Folio API allows customers and partners to write code that can read and manipulate their data in Folio.

Technology

The API uses GraphQL as the protocol to access data. This documentation does not include a GraphQL tutorial, as there are many good ones already. A good starting point is the official GraphQL documentation and its list of resources.

Getting started

The easiest way to play around with the API is to use the playground. It's an interactive UI to write and send requests to the API.

All requests to the API go to https://api.folio.no/graphql as HTTP POST requests. The requests must include an authorization header with the API token of the consumer. The header is called "Authorization" and the value must be "Bearer <your token goes here>".

Core concepts

The API exposes a number of object types. The most important of these are Organization, Agent and Activity.

Idempotency and error recovery

Some mutations support an optional idempotencyKey parameter. When the parameter is set, a mutation will only run once for a given key. Thus it is safe to retry a mutation that may have failed by using the same idempotency key. The mutation will only execute once.

Note (2022-10-14): For the time being, idempotency keys are added to the GraphQL APIs, but not activated in underlying systems. Thus idempotency is not guaranteed yet, but the ID is useful to help debugging.

Organization

All folio customers are Organizations. They represent companies in Norway with accounts in Folio.

Agent

An Agent is a person or a program that can act on behalf of an organization. For example, all employees in an Organization is represented by an Agent object. Agents can be granted various levels of access to the organization.

Activity

An Activity is a movemnt of funds in one or more of the accounts owned by an Organization. There are three kinds of activities:

  • Transfers. Funds where moved from between accounts owned by the organization
  • Sending funds. Payments were made from one of the organizations acocunts, by using the online bank or a Folio card.
  • Receiving funds. Payment was received into one of the organizations accounts.

Activities are always owned by an organization, and may be initiated by an agent.

Examples

Curl

curl 'https://dev.api.folio.no/graphql' \
  -H 'Authorization: Bearer foobar' \
  -H 'content-type: application/json' \
  --data-binary '{"operationName":null,"variables":{},"query":"{\norganization {\nname\norganizationNumber\nagents {\nstructuredName {\ndisplay\n}\nemail\n}\n}\n}\n"}'

Get all activities

{
  activities {
    id
    amount {
      raw
    }
  }
}

Reference

Queries

activities

Type: ActivitiesReply!

Get all activities in the date range, inclusive. The end date may be omitted, to get all activities starting at the start date. The result includes activities that are both booked and in progress.

NameDescription
between (OpenEndedDatePeriod!)

activity

Type: Activity

Get a single activity. If the activity is not found, the activity is null.

NameDescription
id (ID!)

bankStatements

Type: [BankStatement!]!

NameDescription
yearMonth (YearMonth!)

bankStatementsByPeriod

Type: [BankStatementByPeriod!]!

Get links to downloadable bank statements for the orgs account types. The files can be downloaded using the same credentials used for GraphQL.

NameDescription
endDate (IsoDate!)

End date is inclusive

startDate (IsoDate!)

Start date is inclusive

bookedActivities

Type: BookedActivitiesReply!

Get all booked activities in the date range, inclusive. The end date may be the same as the start date.

NameDescription
bookedBetween (DatePeriod!)

employee

Type: Agent!

An agent that's a member of the current organization.

NameDescription
fid (ID!)

ledgerInfo

Type: LedgerInfo!

No arguments

organization

Type: Organization!

The organization of the current agent.

NameDescription
orgNum (OrganizationNumber)

salaryPayment

Type: SalaryPayment!

NameDescription
fid (UUID!)

Mutations

disableIntegration

Type: DisableIntegrationReply!

Disables the integration client. This means revoking the tokens and user consent that was issued when the user enabled the integration. This is essentially a "self destruct". After issuing this call, no more calls with the credentials are allowed.

No arguments

registerPayment

Type: RegisterPaymentReply!

Register a payment for approval. A human must confirm the payment in Folio's UI before it can go through. To be used by accounting systems.

NameDescription
input (RegisterPaymentInput!)

registerSalaryPayment

Type: RegisterSalaryPaymentReply!

Create an unapproved salary payment, ready for approval in Folio.

NameDescription
input (RegisterSalaryPaymentInput!)

sendEmail

Type: Int!

Allows sending emails with attachments. Return value represents the number of emails sent.

Each email will cap out at 19mb in attachments, and any single attachment larger than 19mb will be rejected.

NameDescription
emailInput (CustomEmailInput!)

setAccountReconciliationDate

Type: SetReconciliationReply!

Tell Folio that the accounting system and its user has reconciled (avstemt) the given account up to and including the date.

NameDescription
accountNumber (AccountNumber!)
date (IsoDate!)

setActivityComplete

Type: Boolean!

Mark a single activity as complete from external system. Prevents activities to be in the 'mangler noe' tab when it is marked complete outside Folio.

NameDescription
complete (Boolean!)

Flag indicating booked/done status

id (UUID!)

Unique ID of an activity

Subscriptions

No Subscription object

Scalars

AccountNumber

A Norwegian bank account number, represented as a string with no spaces or dots.

AlphabeticCurrencyCode

An alpha code in ISO4217 format.

Amount

A string representation of a currency amount. Using '.' for decimal points.

Boolean

The Boolean scalar type represents true or false.

CountryCode

A country code in ISO3166 format.

Float

The Float scalar type represents signed double-precision fractional values as specified by IEEE 754.

ID

The ID scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "4") or integer (such as 4) input value will be accepted as an ID.

Int

The Int scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.

IsoDate

A date in ISO 8601 / RFC 3339 format, in the format yyyy-MM-dd. See https://tc39.es/proposal-temporal/docs/plaindate.html.

IsoUtcDateTime

A date and time in ISO 8601 / RFC 3339 format. See https://tc39.es/proposal-temporal/docs/instant.html.

KidNumber

A Norwegian KID number. See https://no.wikipedia.org/wiki/KID-nummer.

NumericCurrencyCode

A numeric currency code in ISO4217 format. While the codes are numeric, the type is represented as a string because there are systems that use zero-padded strings to look up the code currency.

OrganizationNumber

An organization number registered in brreg or temporarily assigned during onboarding.

PhoneNumber

A phone number.

SafeInt

The SafeInt scalar type represents non-fractional signed whole numeric values that are considered safe as defined by the ECMAScript specification.

String

The String scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.

Upload

The Upload scalar type represents a file upload.

URL

A string representation of a URL.

UUID

A unique ID as specified by https://www.rfc-editor.org/rfc/rfc4122.

YearMonth

A month and year, in ISO 8601 / RFC 3339 format. For example 2020-05. See https://tc39.es/proposal-temporal/docs/plainyearmonth.html.

Objects

AccountingSystemPaymentInformation

NameDescription
ledgerAccount (Int)

Ledger account as a number provided by accounting system when registering a payment.

registeredBy (String)

String provided by accounting system when registering a payment.

AccountsInfo

NameDescription
accounts ([OrganizationAccount!]!)
totalBalance (String)

ActivitiesReply

NameDescription
items ([Activity!]!)

The list of activities in the period

Activity

A movement of funds involving one or more accounts belonging to an organization. For example when:

  • Using a Folio card at a physical terminal.
  • Using a Folio card online.
  • Paying an invoice.
  • Receiving payment.
  • Moving funds between the organizations accounts.

Transactions always have two parties: a debtor and creditor side. The party that pays and receives funds. In the case of internal transfers, both parties are present, and are in the same organization.

Transactions can mutate from the point they are created until the time they are completed. Mutations are caused by more information coming from banking systems, such as daily transfers and synchronization with credit card issuers.

NameDescription
accountingCategoryInfo (ActivityLedgerCategoryInfo!)

The selected category for the activity.

booked (Boolean!)

True if the funds have finished moving.

bookedAt (IsoDate)

The date on which the movement of funds was completed.

card (Card)

If a card was involved in the activity, it's available here, as well as via the debtor or creditor."

completed (Boolean!)

True when the event is booked, there is a category selected, and all the requirements for the category is fulfilled.

currencyAmount (AmountInfo!)

Same as nokAmount but in the currency that was used for the activity.

external (Boolean!)

Flag indicating if the event was created outside of Folio or not.

externalId (ID)

External ID provided when creating a payment.

id (UUID!)

Unique ID of an activity

merchant (Merchant)

If a merchant is involved, it will be here as well as via the debtor or creditor.

nokAmount (AmountInfo!)

The amount of money that moved in our out of the organization. If this is an internal transfer, the amount is 0. The paidFrom and paidTo objects contain the amounts involved in the activity for each direction.

organization (Organization!)

The organization this activity belongs to.

paidFrom (ActivityParty!)

The party to the activity that sent funds.

paidTo (ActivityParty!)

The party to the activity that received funds.

payment (PaymentInfo)

The associated payment object.

physicalTerminal (Boolean!)

Flag indicating if the activity was triggered by interacting with a physical payment terminal.

receipts ([Receipt!]!)

List of receipts attached as documentation to the event.

requirements (ActivityRequirements!)

Any requirements for the activity to be considered complete. Always defined, with the only requirement being Category if one isn't selected.

role (OrganizationActivityRole!)

Indicate if money was paid to the org, paid from the org or moved within the org.

salaryPayment (SalaryPayment)

The salary payment this activity belongs to. null if activity is not part of a salary payment.

startedAt (IsoUtcDateTime!)

The timestamp when the activity was started.

strings (ActivityStrings!)

Human readable strings appropriate for display.

unstable_annotations (ActivityAnnotations!)

For internal use.

unstable_debugInformation (ActivityDebugInformation)

Will be null if agent does not have access.

unstable_isInternalTransferLeg (Boolean!)

Flag that is true if this activity is a leg of an internal transfer that should be ignored by the consumer. This is a temporary workaround that will be removed as soon as the API stops notifying consumers about activities they should not need to know about.

unstable_mcc (String)

The MCC of the activity if there was one.

unstable_transactionType (Int)

Null if the transaction does not exist. This will turn into an enum instead of the integer value at some point.

voucherDownloadUrl (URL!)

The URL where the voucher PDF document can be downloaded from.

ActivityAnnotation

NameDescription
addedAt (IsoUtcDateTime!)
addedBy (Agent)
body (String!)
id (UUID!)

ActivityAnnotations

NameDescription
noReceiptNeeded (ActivityAnnotation)
note (ActivityAnnotation)
participants (ActivityAnnotation)
purpose (ActivityAnnotation)
receiptLost (ActivityAnnotation)

ActivityDebugInformation

NameDescription
rawBankInformation (String!)

Raw data from the underlying bank infrastructure.

ActivityLedgerAccount

NameDescription
accountName (String!)
accountNumber (LedgerAccountNumber!)
vat (VatData!)

ActivityLedgerCategoryInfo

NameDescription
category (LedgerCategoryItem)
kind (LedgerCategoryInfoKind!)

ActivityParty

One part of a transaction, either the one paying or the one getting paid.

NameDescription
account (BankAccount)

If no account information is known yet, this is null. For accounts belonging to the organization, it contains the complete account information. For accounts that don't belong to the org, only the account number and our best guess at an account name is available.

activity (Activity!)

The transaction of this party.

card (Card)

If the party used a card, card info is here.

currencyAmount (AmountInfo!)

The amount of money that moved, in the currency it was moved

ledgerAccount (ActivityLedgerAccount)

If a ledger account has been selected, it's here.

merchant (Merchant)

The merchant information about the party, if available.

nokAmount (AmountInfo!)

The amount of money that moved, in Norwegian krone

role (ActivityPartyKind!)
strings (ActivityPartyStrings!)

Human readable strings about the activity appropriate for display.

ActivityPartyStrings

NameDescription
accountNameOrPartyName (String)

If the party is the organization of the API user, and we know which account was used, returns the account name. Otherwise, the same as the name field. If there is no information about the party, returns null.

| Party type | Result | |-------------------------------------------------|-----------------| | Ola's card account in MyOrg Inc | "Ola" | | Organization's operational account | "driftskonto" | | Other organization called "Vendor Inc" | "Vendor Inc" | | Other organization we have no information about | null |

accountTypeOrPartyName (String)

If the party is the organization of the API user, and we know which account was used, returns the account type. Otherwise, the same as the name field. If there is no information about the party, returns null.

| Party type | Result | |-------------------------------------------------|-----------------| | Ola's card account in MyOrg Inc | "kortkonto" | | Organization's operational account | "driftskonto" | | Other organization called "Vendor Inc" | "Vendor Inc" | | Other organization we have no information about | null |

partyName (String)

The best guess at the name of the party, by looking at accounts, merchant info, OCR lookup and text fields on the raw event. If there is no information about the party, returns null.

| Party type | Result | |-------------------------------------------------|----------------| | Ola's card account in MyOrg Inc | "MyOrg Inc" | | Organization's operational account | "MyOrg Inc" | | Other organization called "Vendor Inc" | "Vendor Inc" | | Other organization we have no information about | null |

ActivityRequirements

NameDescription
allRequirements ([ActivityRequirement!]!)

All the requirements for the event.

allRequirementsMet (Boolean!)

Flag indicating if the requirements of the event have been met.

metRequirementCount (Int!)

The number of requirements that have been met for the event.

totalRequirementCount (Int!)

The number of requirements that must be met for the event.

unmetRequirements ([ActivityRequirement!]!)

The requirements for the event that have not been met.

ActivityStrings

NameDescription
description (String!)
rawDescription (String)
unstable_kid (KidNumber)
unstable_message (String)
unstable_transactionDescription (String!)
unstable_transactionSubtitle (String)

Agent

An agent is a person or program that can act on behalf of an organization.

All agents are attached to a User. A person has a single User object, and have Agent objects for each organization they can act on behalf of.

Agents can be assigned roles and capabilities, so for example an agent can be given the "CFO" role, which allows them to export the organizations events.

NameDescription
accountsInfo (AccountsInfo!)

The accounts the agent is allowed to access.

cardAccount (CardAccount)

The card account, if the agent has a card.

cardAccountsInfo (AccountsInfo!)

The cards assigned to the agent

email (String)

Email address of the agent. A single user can have more than one agent, and each agent can have their own email address.

id (UUID!)

Unique ID of the agent.

mobileNumber (PhoneNumber)

Mobile phone number of the agent. A single user can have more than one agent, and each agent can have their own mobile phone number.

organization (Organization!)

Organization of which the agent is a member.

structuredName (Name!)

The name of the agent, in various versions. This field will be renamed to name once usage of the current name field drops to zero.

AmountInfo

Representation of an amount, and the currency of the amount.

NameDescription
alphabeticCode (AlphabeticCurrencyCode!)

The alphabetic currency code from https://en.wikipedia.org/wiki/ISO_4217 .

asAbsoluteMinorUnit (SafeInt!)

Absolute version of asMinorUnit.

asAbsoluteNumber (Float!)

Absolute version of asNumber.

asAbsoluteNumericString (String!)

Absolute version of asNumericString.

asMinorUnit (SafeInt!)

The amount as an unsigned number in the minor unit of the currency. The amount 49.90 in NOK is represented as 499000. That is, the amount in øre. See https://en.wikipedia.org/wiki/ISO_4217 for more information about minor units.

asNumber (Float!)

The amount as an unsigned floating point number.

asNumericString (String!)

The amount as an unsigned number, as a string with decimals in a format suitable to parse as a floating point number. The number of decimals will always match minorUnitSize. For example:

  • 452 NOK: 452.00
  • 1 NOK: 1.00
  • 1.99 NOK: 1.99
  • 5435 YEN: 5435
  • 10.5 TND: 10.500
isNegative (Boolean!)

Flag indicating if the amount is negative.

isNok (Boolean!)

Flag to tell if the amount is in Norwegian krone. Useful as a shorthand to avoid doing comparisons with numericCode/alphabeticCode to check if we're in the "native" Folio currency.

minorUnitSize (Int!)

The "minor unit" size of the currency. That is, how many digits are used to represent fractions of the currency. For NOK, it is 2 because an øre amount is represented by two digits, 0-99.

numericCode (NumericCurrencyCode!)

The numeric currency code from https://en.wikipedia.org/wiki/ISO_4217 .

BankStatement

NameDescription
accountType (OrganizationAccountType!)
url (URL!)

BankStatementByPeriod

NameDescription
accountType (OrganizationAccountType!)
url (URL!)

BookedActivitiesReply

NameDescription
accountBalances ([PeriodAccountBalance!]!)

Balances for each bank account that was used in the requested period.

accountTypeBalances ([PeriodAccountTypeBalance!]!)

Balances for each bank account type. Only includes the account types that have a valid balance for the given date.

items ([Activity!]!)

The list of activities in the period

periodComplete (Boolean!)

True if we are certain that the period is complete, and that we have balances for all accounts for the given period.

Card

A debit card owned by an agent of the organization and connected to one of the organizations bank accounts. Note: Neither the card number, nor the PIN, are available through the API.

NameDescription
accountNumber (AccountNumber!)

The account number that's the source of funds for the card.

agent (Agent!)
id (UUID!)

Id of the card in Folio.

name (String)

A name describing the card. By default this is the name of the agent the card has been issued to.

state (CardState!)

CardAccount

NameDescription
account (OrganizationAccount!)
accountNumber (AccountNumber!)
card (Card)

DisableIntegrationReply

NameDescription
disabled (Boolean!)

EmployeeWithCard

NameDescription
accounts ([OrganizationAccount!]!)
agent (Agent!)

ExportAccounts

Information about the bank accounts in the organization, when used in the context of exports. These are the 'authoritative' versions of the bank accounts in the organization. The purpose of this is that when exporting, there should be a single bank account number representing every card bank account. In the future, this may apply to other account types as well.

NameDescription
cardAccount (OrganizationAccount!)

For exports we only show a single account rather than every individual card account.

operationalAccount (OrganizationAccount!)
savingsAccount (OrganizationAccount)

The authoritative savings account, if the org has a savings account.

taxAccount (OrganizationAccount)

The authoritative tax account, if the org has a tax account.

GenericBankAccount

NameDescription
accountNumber (AccountNumber!)
bankName (String)

GeoLocation

NameDescription
lat (Float!)
lng (Float!)

LedgerAccount

The ledger account name and number for a category in Folio. There are account numbers for Folio, as well as a number of accounting systems. In some cases a category maps to different ledger accounts in different systems For example: The category "Lunsj" in Folio maps to the ledger account number `6800`, except for when using Fiken, where it maps to `6801`.

NameDescription
code (Int!)
fiken (Int!)
folio (Int!)
name (String!)
powerOfficeGo (Int!)
tripletex (Int!)
uniEconomy (Int!)
vismaEAccounting (Int!)

LedgerAccountNumber

The ledger account numbers for Folio, and mapped to accounting systems. This is useful in cases where an accounting system uses a different chart of accounts (kontoplan) than that in Folio.

NameDescription
fiken (Int!)
folio (Int!)
powerOfficeGo (Int!)
tripletex (Int!)
uniEconomy (Int!)
vismaEAccounting (Int!)

LedgerCategory

NameDescription
id (ID!)
items ([LedgerCategoryItem!]!)
subtitle (String)
title (String!)

LedgerCategoryItem

NameDescription
account (LedgerAccount!)
hidden (Boolean!)
id (ID!)
parent (LedgerCategory!)
requirements ([LedgerCategoryItemRequirement!]!)
subtitle (String)
synonyms ([String!]!)
title (String!)
vat (VatData!)

LedgerInfo

NameDescription
groups ([LedgerCategory!]!)
items ([LedgerCategoryItem!]!)

Merchant

NameDescription
address (String)
city (String)
countryCode (CountryCode)
geoLocation (GeoLocation)
googlePlacesID (String)
id (UUID!)
name (String!)
organizationNumber (OrganizationNumber)
postalCode (String)
verified (Boolean)

Has been checked by a human

Name

The name of an agent in various representations.

NameDescription
display (String!)
first (String)
full (String!)
last (String)
legal (String)
middle (String)

Organization

An organization that's a customer of Folio.

Organizations have:

  • agents: People or programs acting on behalf of the organization
  • accounts: Bank accounts owned by the organization
  • events: Transaction events affecting any of the organization's accounts

NameDescription
accountsInfo (AccountsInfo!)

Information about the bank accounts owned by the organization that the agent is allowed to see.

agents ([Agent!]!)

All the agents that have a role in the organization. Requires the current agent to have access to this information.

employeesWithCards ([EmployeeWithCard!]!)
exportAccounts (ExportAccounts!)
name (String!)

The display name of the organization. Starts as identical to the name as registered in brreg but can be changed.

onboardingDate (IsoDate!)

Date on which the organization signed up for Folio.

operationalAccount (OrganizationAccount!)

The operational account of the organizations. Organizations will have exactly one or zero operational accounts. There is no operational account at the start of onboarding, before the contracts are signed.

organizationNumber (OrganizationNumber!)
savingsAccount (OrganizationAccount)

The authoritative savings account, if the org has a savings account.

OrganizationAccount

An account owned by an organization. All account numbers have "3606" as the first four digits. This indicates that it's an account in Folio.

NameDescription
accountNumber (AccountNumber!)

The real account number of the bank account.

balanceNok (AmountInfo)

The current balance of the account. Some agents will have permission to know that an account exists, but not what its balance is, so this field may be null.

bankName (String)

The name of the bank that issued the bank account. Looked up from the IBAN-BIC table: https://bits.no/iban

cards ([Card!]!)

Debit cards that draw money from this account.

iban (String)

The IBAN used if transferring money to the bank account from a non-Norwegian bank account.

interestRate (String!)

Interest rate for this account. 0 for all accounts except savings accounts. Represented as a floating number.

ledgerAccountNumber (String!)

The ledger account number used in folio for transactions involving this bank account type.

name (String!)

Name of the account. The name is currently assigned by Folio and not changeable.

organization (Organization!)
state (OrganizationAccountState!)
type (OrganizationAccountType!)
unstable_exportAccountNumber (AccountNumber!)

The authoritative bank account number for the account type. Used for export

PaymentInfo

NameDescription
accountingSystemInformation (AccountingSystemPaymentInformation)

Information provided by the accounting system, if any.

activity (Activity!)
confirmed (Boolean!)
createdAt (IsoUtcDateTime!)
createdBy (Agent)
creditorAccount (AccountNumber!)
creditorName (String!)
debtorAccount (AccountNumber!)
debtorAccountName (String)
executionDate (IsoUtcDateTime!)
kid (KidNumber)
message (String)
nokAmount (AmountInfo!)
paymentId (UUID!)
status (PaymentStatus!)

PeriodAccountBalance

The balance for a single bank account when entering and exiting the period.

NameDescription
accountNumber (AccountNumber!)
incomingBalanceNok (AmountInfo)
outgoingBalanceNok (AmountInfo!)
periodComplete (Boolean!)

True if the period is completed for this account. If this is false, the balances are not up to date for all movements in the period.

type (OrganizationAccountType!)

PeriodAccountTypeBalance

The balance for a bank account type when entering and exiting the period. While there should be only a single tax and operational account, there can be multiple card accounts, and it's convenient to treat them as a single account for accounting purposes.

NameDescription
incomingBalanceNok (AmountInfo)
outgoingBalanceNok (AmountInfo!)
periodComplete (Boolean!)

True if the period is completed for this account type. If this is false, the balances are not up to date for all movements in the period.

type (OrganizationAccountType!)

Receipt

A receipt that has been uploaded as documentation for an event. Receipts can be images or PDF files.

NameDescription
downloadUrl (URL!)
filename (String)

The file name as it was sent by the agent that uploaded the receipt.

fileSize (Int!)

Size of original attachment in bytes.

id (UUID!)

Unique ID of the receipt.

images (ReceiptImages!)
isInvoice (Boolean!)
isSystemReceipt (Boolean!)

The receipt was generated by Folio, not uploaded by the user

mime (String!)

Mime type of the receipt file. The supported types are:

  • application/pdf
  • image/jpeg
  • image/png
uploadedAt (IsoUtcDateTime!)
uploadedBy (Agent)

ReceiptImages

NameDescription
croppedUrl (URL)

RegisterPaymentReply

NameDescription
activity (Activity!)
payment (PaymentInfo!)

RegisterSalaryPaymentReply

NameDescription
payment (SalaryPayment!)
paymentId (UUID!)

SalaryPayment

Represents a salary payment batch, which consists of one or more salary payments to employees, and optionally tax payments.

NameDescription
activities ([Activity!]!)
amount (Amount!)
bulkStatus (SalaryPaymentStatus!)

Status of the bulk payment as a whole

executionDate (IsoUtcDateTime!)
externalId (ID)

External ID provided when creating the payment.

id (UUID!)

SetReconciliationReply

NameDescription
accountNumber (AccountNumber!)
date (IsoDate!)

VatData

NameDescription
code (Int!)
codeString (String!)
name (String!)
rate (String!)

Interfaces

BankAccount

NameDescription
accountNumber (AccountNumber!)
bankName (String)

Input object types

CustomEmailInput

NameDescription
attachments ([EmailAttachment!]!)
from (String!)
subject (String!)
to (String!)

DatePeriod

NameDescription
endDate (IsoDate!)
startDate (IsoDate!)

EmailAttachment

NameDescription
filename (String)
url (URL!)

OpenEndedDatePeriod

NameDescription
endDate (IsoDate)
startDate (IsoDate!)

PaymentAttachment

NameDescription
filename (String)
mime (String)

If neither url nor filename have a file extension mime can be inferred from, use this field.

url (URL!)

A public URL (i.e. needs no authentication) the attachment can be fetched from.

RegisterPaymentInput

NameDescription
amount (Amount!)
binaryAttachments ([Upload!])
creditorAccount (AccountNumber!)
creditorName (String!)
date (IsoDate!)
debtorAccountType (PaymentAccountType)

Defaults to Operational

externalId (ID)

ID provided by external system for own reference.

externalURL (URL)

A URL used to link back to the external system from Folio's UI.

idempotencyKey (String)

Tracks if the same request has already been performed. Allows API users to retry failed requests without the risk of performing mutations multiple times.

kid (KidNumber)

One of message or kid must be provided - but not both.

ledgerAccountNumber (String)

E.g. 6800 for "Kontorrekvisita". If an account Folio does not recognize is passed, it is stored separately, but Activity.accountingCategory is left blank.

message (String)

One of message or kid must be provided - but not both.

registeredBy (String)

String displayed in Folio to explain where payment comes from.

urlAttachments ([PaymentAttachment!])

RegisterSalaryPaymentInput

NameDescription
dueDate (IsoDate!)
externalId (ID)

External ID provided when creating a salary payment.

externalURL (URL)

A URL used to link back to the external system from Folio's UI.

idempotencyKey (String)

Tracks if the same request has already been performed. Allows API users to retry failed requests without the risk of performing mutations multiple times.

recipients ([SalaryRecipient!]!)

The individual salary payments.

registeredBy (String)
taxPayments ([TaxPayment!])

Any tax payments made as part for the salary payment.

SalaryRecipient

NameDescription
accountNumber (AccountNumber!)
amount (Amount!)
externalId (ID)

External ID for a specific payment.

message (String!)
name (String!)

TaxPayment

NameDescription
amount (Amount!)
externalId (ID)

External ID for a specific payment.

message (String!)

Enums

ActivityPartyKind

paidFrom
paidTo

ActivityRequirement

Category
Participants
Purpose
Receipt

BackendErrorCode

The error code from backend services. GraphQLErrors with an extension with code equal to BackendError, there will be an errors array containing objects where the code is one of the ones in this enum.

AccessDenied
AlreadyExists
BadTokenSignature
BankIDMobileCertificateBlocked
BankIDSessionAbortedByUser
BankIDSessionBadMobileOrBirthDate
BankIDSessionGenericError
BankIDSessionInvalidated
BankIDSessionMobileNumberAlreadyInUse
BankIDSessionMobileOperatorFailure
BankIDSessionTimeout
BulkPaymentPartiallyUnapproved
Cancelled
CardActivityAccountError
CardBadEncryptedPinData
CardDeleted
DisabledAgent
ENKIsAlreadySPVCustomer
Forbidden
IncorrectTokenType
InternalError
InvalidEmailAddress
InvalidParameter
InvalidPDF
InvalidTokenFormat
NotFound
OAuthBadRedirectURL
OAuthClientNotFound
OAuthInvalidGrant
OAuthInvalidScope
OAuthUnauthorizedClient
OnboardingAMLFailed
PasswordProtectedPDF
PaymentAccountBlocked
PaymentAccountUnauthorized
PaymentAlreadyAuthorised
PaymentAlreadyCompleted
PaymentAlreadyInProcess
PaymentCreditorAccountBlocked
PaymentCreditorAccountClosed
PaymentCreditorAccountFailsAML
PaymentIncorrectUserSigned
PaymentInsufficientFunds
PaymentInvalidCreditorAccount
PaymentInvalidKID
PaymentKIDRequired
PaymentNoKIDAgreement
PaymentNotTreasuryAccount
PaymentOutOfSync
SPVAgentNotFound
SPVGenericError
Timeout
TokenExpired
TokenNoLongerValid
Unspecified

CardState

Active
Blocked
Deleted
FraudBlocked
NotActivated
Unknown

LedgerCategoryInfoKind

All events have a ledger category. They usually start out as a guess, which an agent confirms or changes.

Guessed

We have guessed this info.

Missing

We weren't able to guess, or have no reasonable guess.

Selected

The user has selected this category.

Unknown

The user has indicated that accountant / grown-up must check.

LedgerCategoryItemRequirement

Participants
Purpose
Receipt

OrganizationAccountState

Active
Inactive

Account have is no longer in use, but still exists, as it may be referenced in events.

Reserved

Account number has been provisioned, but the account is not activated.

Unspecified

OrganizationAccountType

Card
Operational
Savings
Tax
Unspecified

OrganizationActivityRole

paidFrom
paidFromAndTo
paidTo

PaymentAccountType

Operational
Tax

PaymentStatus

PaymentStatusCancelled

Payment was cancelled.

PaymentStatusCompleted

Payment has been completed.

PaymentStatusInitiated

Payment has been initiated in the bank, and is awaiting authorization.

PaymentStatusInProcess

Payment has been authorized and accepted for execution.

PaymentStatusInsufficientFunds

Payment is still active, but cannot be completed due to insufficient funds.

PaymentStatusNew

Payment has been created, but not submitted to the bank.

PaymentStatusRejected

Payment was rejected, possibly due to insufficient funds.

PaymentStatusUnspecified

SalaryPaymentStatus

The status of a salary payment when seen as a complete batch of payments. The separate payments included in the batch may have different statuses, this state reflects what the combination of statuses mean.

Cancelled

A salary payment where every payment has the PaymentStatusCancelled state.

Completed

A salary payment where at least one payment is completed, and the rest are either completed or canceled. Canceled payments are allowed here, since users may chose to cancel parts of a salary payment, which is not considered a payment failure.

Failed

Either: the salary payment has one or more payments that have the PaymentStatusRejected. Or: The salary payment has payments that are both PaymentStatusInitiated and PaymentStatusCompleted, indicating that there may have been errors when creating some of the payments. In this state, the salary payment may be approved again, in which case it will transition to the InProcess state.

InProcess

A salary payment that has been approved. It contains payments with either of the PaymentStatusInitiated, PaymentStatusInprocess or PaymentStatusCompleted statuses. PaymentStatusCompleted will be present if the salary payment has failed and then been approved again.

InsufficientFunds

The salary payment has one or more payments that could not be executed due to insufficient funds in the debtor account. Salary payments in this state is automatically retried, and will be completed if sufficient funds become available. After a period of time, if funds are not available, the salary payment may transition to the Failed state.

New

A salary payment that has not been approved. Every payment is in the PaymentStatusNew state or PaymentStatusInitiated state.

Schema

Download the schema.

directive @isAuthenticated on FIELD_DEFINITION

directive @hasOrgSelected on FIELD_DEFINITION

directive @hasBackofficeAccess on FIELD_DEFINITION

directive @public on FIELD_DEFINITION | INPUT_FIELD_DEFINITION

"""
A string representation of a currency amount. Using '.' for decimal points.
"""
scalar Amount

"""
A Norwegian bank account number, represented as a string with no spaces or dots.
"""
scalar AccountNumber

"""
A country code in [ISO3166](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes)
format.
"""
scalar CountryCode

"""
A numeric currency code in [ISO4217](https://no.wikipedia.org/wiki/ISO_4217)
format. While the codes are numeric, the type is represented as a string because
there are systems that use zero-padded strings to look up the code currency.
"""
scalar NumericCurrencyCode

"""
An alpha code in [ISO4217](https://no.wikipedia.org/wiki/ISO_4217) format.
"""
scalar AlphabeticCurrencyCode

"""A phone number."""
scalar PhoneNumber

"""
The `SafeInt` scalar type represents non-fractional signed whole numeric values that are considered safe as defined by the ECMAScript specification.
"""
scalar SafeInt

"""
A date in ISO 8601 / RFC 3339 format, in the format yyyy-MM-dd. See https://tc39.es/proposal-temporal/docs/plaindate.html.
"""
scalar IsoDate

"""
A date and time in ISO 8601 / RFC 3339 format. See https://tc39.es/proposal-temporal/docs/instant.html.
"""
scalar IsoUtcDateTime

"""
A month and year, in ISO 8601 / RFC 3339 format. For example 2020-05. See https://tc39.es/proposal-temporal/docs/plainyearmonth.html.
"""
scalar YearMonth

"""A Norwegian KID number. See https://no.wikipedia.org/wiki/KID-nummer."""
scalar KidNumber

"""
An organization number registered in brreg or temporarily assigned during onboarding.
"""
scalar OrganizationNumber

"""The `Upload` scalar type represents a file upload."""
scalar Upload

"""A string representation of a URL."""
scalar URL

"""A unique ID as specified by https://www.rfc-editor.org/rfc/rfc4122."""
scalar UUID

type AccountsInfo {
  totalBalance: String
  accounts: [OrganizationAccount!]!
}

type BankStatement {
  url: URL!
  accountType: OrganizationAccountType!
}

type BankStatementByPeriod {
  url: URL!
  accountType: OrganizationAccountType!
}

enum OrganizationAccountType {
  Unspecified
  Card
  Operational
  Tax
  Savings
}

enum PaymentAccountType {
  Operational
  Tax
}

type AccountingSystemPaymentInformation {
  """String provided by accounting system when registering a payment."""
  registeredBy: String

  """
  Ledger account as a number provided by accounting system when registering a payment.
  """
  ledgerAccount: Int
}

"""
An organization that's a customer of Folio.

Organizations have:

- agents: People or programs acting on behalf of the organization
- accounts: Bank accounts owned by the organization
- events: Transaction events affecting any of the organization's accounts
"""
type Organization {
  organizationNumber: OrganizationNumber!

  """
  The display name of the organization. Starts as identical to the name as
  registered in brreg but can be changed.
  """
  name: String!

  """
  The operational account of the organizations. Organizations will have exactly
  one or zero operational accounts. There is no operational account at the
  start of onboarding, before the contracts are signed.
  """
  operationalAccount: OrganizationAccount!

  """The authoritative savings account, if the org has a savings account."""
  savingsAccount: OrganizationAccount

  """Date on which the organization signed up for Folio."""
  onboardingDate: IsoDate!

  """
  All the agents that have a role in the organization. Requires the current
  agent to have access to this information.
  """
  agents: [Agent!]!

  """
  Information about the bank accounts owned by the organization that the agent
  is allowed to see.
  """
  accountsInfo: AccountsInfo!
  employeesWithCards: [EmployeeWithCard!]!
  exportAccounts: ExportAccounts!
}

type EmployeeWithCard {
  agent: Agent!
  accounts: [OrganizationAccount!]!
}

enum OrganizationAccountState {
  Unspecified

  """Account number has been provisioned, but the account is not activated."""
  Reserved
  Active

  """
  Account have is no longer in use, but still exists, as it may be referenced
  in events.
  """
  Inactive
}

interface BankAccount {
  accountNumber: AccountNumber!
  bankName: String
}

"""
An account owned by an organization. All account numbers have "3606" as the
first four digits. This indicates that it's an account in Folio.
"""
type OrganizationAccount implements BankAccount {
  type: OrganizationAccountType!
  state: OrganizationAccountState!

  """
  Name of the account. The name is currently assigned by Folio and not
  changeable.
  """
  name: String!

  """The real account number of the bank account."""
  accountNumber: AccountNumber!

  """
  The name of the bank that issued the bank account. Looked up from the IBAN-BIC
  table: https://bits.no/iban
  """
  bankName: String

  """
  The IBAN used if transferring money to the bank account from a non-Norwegian
  bank account.
  """
  iban: String

  """
  The current balance of the account.
  Some agents will have permission to know that an account exists, but not what
  its balance is, so this field may be null.
  """
  balanceNok: AmountInfo
  organization: Organization!

  """Debit cards that draw money from this account."""
  cards: [Card!]!

  """
  The ledger account number used in folio for transactions involving this bank
  account type.
  """
  ledgerAccountNumber: String!

  """
  Interest rate for this account. 0 for all accounts except savings accounts. Represented as a floating number.
  """
  interestRate: String!

  """
  The authoritative bank account number for the account type. Used for export
  """
  unstable_exportAccountNumber: AccountNumber!
}

enum CardState {
  Unknown
  Active
  Blocked
  NotActivated
  Deleted
  FraudBlocked
}

"""The name of an agent in various representations."""
type Name {
  full: String!
  display: String!
  legal: String
  first: String
  middle: String
  last: String
}

"""
An agent is a person or program that can act on behalf of an organization.

All agents are attached to a `User`. A person has a single User object, and
have `Agent` objects for each organization they can act on behalf of.

Agents can be assigned roles and capabilities, so for example an agent can be
given the "CFO" role, which allows them to export the organizations events.
"""
type Agent {
  """Unique ID of the agent."""
  id: UUID!

  """
  The name of the agent, in various versions. This field will be renamed to
  `name` once usage of the current `name` field drops to zero.
  """
  structuredName: Name!

  """
  Email address of the agent. A single user can have more than one agent, and
  each agent can have their own email address.
  """
  email: String

  """
  Mobile phone number of the agent. A single user can have more than one agent,
  and each agent can have their own mobile phone number.
  """
  mobileNumber: PhoneNumber

  """The card account, if the agent has a card."""
  cardAccount: CardAccount

  """Organization of which the agent is a member."""
  organization: Organization!

  """The accounts the agent is allowed to access."""
  accountsInfo: AccountsInfo!

  """The cards assigned to the agent"""
  cardAccountsInfo: AccountsInfo!
}

"""
A receipt that has been uploaded as documentation for an event.
Receipts can be images or PDF files.
"""
type Receipt {
  """Unique ID of the receipt."""
  id: UUID!

  """The file name as it was sent by the agent that uploaded the receipt."""
  filename: String

  """
  Mime type of the receipt file. The supported types are:
  
  - application/pdf
  - image/jpeg
  - image/png
  """
  mime: String!
  images: ReceiptImages!
  downloadUrl: URL!

  """Size of original attachment in bytes."""
  fileSize: Int!
  uploadedAt: IsoUtcDateTime!
  uploadedBy: Agent
  isInvoice: Boolean!

  """The receipt was generated by Folio, not uploaded by the user"""
  isSystemReceipt: Boolean!
}

"""
All events have a ledger category. They usually start out as a guess, which
an agent confirms or changes.
"""
enum LedgerCategoryInfoKind {
  """We weren't able to guess, or have no reasonable guess."""
  Missing

  """We have guessed this info."""
  Guessed

  """The user has selected this category."""
  Selected

  """The user has indicated that accountant / grown-up must check."""
  Unknown
}

type ActivityLedgerCategoryInfo {
  kind: LedgerCategoryInfoKind!
  category: LedgerCategoryItem
}

type PaymentInfo {
  paymentId: UUID!
  createdBy: Agent
  createdAt: IsoUtcDateTime!
  creditorName: String!
  creditorAccount: AccountNumber!
  debtorAccount: AccountNumber!
  confirmed: Boolean!
  debtorAccountName: String
  nokAmount: AmountInfo!
  executionDate: IsoUtcDateTime!
  kid: KidNumber
  message: String
  status: PaymentStatus!
  activity: Activity!

  """Information provided by the accounting system, if any."""
  accountingSystemInformation: AccountingSystemPaymentInformation
}

enum PaymentStatus {
  PaymentStatusUnspecified

  """Payment has been created, but not submitted to the bank."""
  PaymentStatusNew

  """Payment has been initiated in the bank, and is awaiting authorization."""
  PaymentStatusInitiated

  """Payment has been authorized and accepted for execution."""
  PaymentStatusInProcess

  """Payment has been completed."""
  PaymentStatusCompleted

  """Payment was cancelled."""
  PaymentStatusCancelled

  """Payment was rejected, possibly due to insufficient funds."""
  PaymentStatusRejected

  """
  Payment is still active, but cannot be completed due to insufficient funds.
  """
  PaymentStatusInsufficientFunds
}

"""
A debit card owned by an agent of the organization and connected to one of the
organizations bank accounts.
*Note:* Neither the card number, nor the PIN, are available through the API.
"""
type Card {
  """Id of the card in Folio."""
  id: UUID!
  state: CardState!
  agent: Agent!

  """The account number that's the source of funds for the card."""
  accountNumber: AccountNumber!

  """
  A name describing the card. By default this is the name of the agent the
  card has been issued to.
  """
  name: String
}

type CardAccount {
  accountNumber: AccountNumber!
  account: OrganizationAccount!
  card: Card
}

input DatePeriod {
  startDate: IsoDate!
  endDate: IsoDate!
}

input OpenEndedDatePeriod {
  startDate: IsoDate!
  endDate: IsoDate
}

"""
The balance for a single bank account when entering and exiting the period.
"""
type PeriodAccountBalance {
  accountNumber: AccountNumber!
  type: OrganizationAccountType!
  incomingBalanceNok: AmountInfo
  outgoingBalanceNok: AmountInfo!

  """
  True if the period is completed for this account. If this is false, the
  balances are not up to date for all movements in the period.
  """
  periodComplete: Boolean!
}

"""
The balance for a bank account type when entering and exiting the period. While
there should be only a single tax and operational account, there can be multiple
card accounts, and it's convenient to treat them as a single account for
accounting purposes.
"""
type PeriodAccountTypeBalance {
  type: OrganizationAccountType!
  incomingBalanceNok: AmountInfo
  outgoingBalanceNok: AmountInfo!

  """
  True if the period is completed for this account type. If this is false, the
  balances are not up to date for all movements in the period.
  """
  periodComplete: Boolean!
}

type BookedActivitiesReply {
  """
  True if we are certain that the period is complete, and that we have balances
  for all accounts for the given period.
  """
  periodComplete: Boolean!

  """The list of activities in the period"""
  items: [Activity!]!

  """Balances for each bank account that was used in the requested period."""
  accountBalances: [PeriodAccountBalance!]!

  """
  Balances for each bank account *type*. Only includes the account types that
  have a valid balance for the given date.
  """
  accountTypeBalances: [PeriodAccountTypeBalance!]!
}

type ActivitiesReply {
  """The list of activities in the period"""
  items: [Activity!]!
}

type Query {
  """
  Get a single activity. If the activity is not found, the activity is null.
  """
  activity(id: ID!): Activity

  """
  Get all activities in the date range, inclusive. The end date may be omitted,
  to get all activities starting at the start date.
  The result includes activities that are both booked and in progress.
  """
  activities(between: OpenEndedDatePeriod!): ActivitiesReply!

  """
  Get all booked activities in the date range, inclusive. The end date may
  be the same as the start date.
  """
  bookedActivities(bookedBetween: DatePeriod!): BookedActivitiesReply!

  """An agent that's a member of the current organization."""
  employee(fid: ID!): Agent!

  """The organization of the current agent."""
  organization(orgNum: OrganizationNumber): Organization!
  salaryPayment(fid: UUID!): SalaryPayment!
  ledgerInfo: LedgerInfo!
  bankStatements(yearMonth: YearMonth!): [BankStatement!]!

  """
  Get links to downloadable bank statements for the orgs account types. The
  files can be downloaded using the same credentials used for GraphQL.
  """
  bankStatementsByPeriod(
    """Start date is inclusive"""
    startDate: IsoDate!

    """End date is inclusive"""
    endDate: IsoDate!
  ): [BankStatementByPeriod!]!
}

type LedgerInfo {
  items: [LedgerCategoryItem!]!
  groups: [LedgerCategory!]!
}

input RegisterPaymentInput {
  """ID provided by external system for own reference."""
  externalId: ID

  """Defaults to Operational"""
  debtorAccountType: PaymentAccountType
  creditorAccount: AccountNumber!
  creditorName: String!
  amount: Amount!

  """One of message _or_ kid must be provided - but not both."""
  message: String

  """One of message _or_ kid must be provided - but not both."""
  kid: KidNumber
  date: IsoDate!

  """
  E.g. 6800 for \"Kontorrekvisita\". If an account Folio does not recognize is
  passed, it is stored separately, but `Activity.accountingCategory` is left
  blank.
  """
  ledgerAccountNumber: String
  binaryAttachments: [Upload!]
  urlAttachments: [PaymentAttachment!]

  """String displayed in Folio to explain where payment comes from."""
  registeredBy: String

  """
  Tracks if the same request has already been performed. Allows API users to
  retry failed requests without the risk of performing mutations multiple times.
  """
  idempotencyKey: String

  """A URL used to link back to the external system from Folio's UI."""
  externalURL: URL
}

type RegisterPaymentReply {
  activity: Activity!
  payment: PaymentInfo!
}

input RegisterSalaryPaymentInput {
  """External ID provided when creating a salary payment."""
  externalId: ID
  dueDate: IsoDate!
  registeredBy: String

  """The individual salary payments."""
  recipients: [SalaryRecipient!]!

  """Any tax payments made as part for the salary payment."""
  taxPayments: [TaxPayment!]

  """
  Tracks if the same request has already been performed. Allows API users to
  retry failed requests without the risk of performing mutations multiple times.
  """
  idempotencyKey: String

  """A URL used to link back to the external system from Folio's UI."""
  externalURL: URL
}

type RegisterSalaryPaymentReply {
  paymentId: UUID!
  payment: SalaryPayment!
}

"""
The status of a salary payment when seen as a complete batch of payments.
The separate payments included in the batch may have different statuses, this
state reflects what the combination of statuses mean.
"""
enum SalaryPaymentStatus {
  """
  A salary payment that has not been approved. Every payment is in the
  `PaymentStatusNew` state or `PaymentStatusInitiated` state.
  """
  New

  """
  A salary payment that has been approved. It contains payments with either of
  the `PaymentStatusInitiated`, `PaymentStatusInprocess` or
  `PaymentStatusCompleted` statuses.
  `PaymentStatusCompleted` will be present if the salary payment has failed and
  then been approved again.
  """
  InProcess

  """
  A salary payment where at least one payment is completed, and the rest are
  either completed or canceled.
  Canceled payments are allowed here, since users may chose to cancel parts
  of a salary payment, which is not considered a payment failure.
  """
  Completed

  """
  A salary payment where every payment has the `PaymentStatusCancelled` state.
  """
  Cancelled

  """
  The salary payment has one or more payments that could not be executed due to
  insufficient funds in the debtor account.
  Salary payments in this state is automatically retried, and will be completed
  if sufficient funds become available.
  After a period of time, if funds are not available, the salary payment may
  transition to the `Failed` state.
  """
  InsufficientFunds

  """
  Either: the salary payment has one or more payments that have the
  `PaymentStatusRejected`. Or: The salary payment has payments that are both
  `PaymentStatusInitiated` and `PaymentStatusCompleted`, indicating that there
  may have been errors when creating some of the payments.
  In this state, the salary payment may be approved again, in which case it
  will transition to the `InProcess` state.
  """
  Failed
}

"""
Represents a salary payment batch, which consists of one or more salary payments
to employees, and optionally tax payments.
"""
type SalaryPayment {
  id: UUID!
  amount: Amount!
  executionDate: IsoUtcDateTime!

  """Status of the bulk payment as a whole"""
  bulkStatus: SalaryPaymentStatus!
  activities: [Activity!]!

  """External ID provided when creating the payment."""
  externalId: ID
}

input SalaryRecipient {
  """External ID for a specific payment."""
  externalId: ID
  name: String!
  accountNumber: AccountNumber!
  amount: Amount!
  message: String!
}

input TaxPayment {
  """External ID for a specific payment."""
  externalId: ID
  amount: Amount!
  message: String!
}

type DisableIntegrationReply {
  disabled: Boolean!
}

type SetReconciliationReply {
  accountNumber: AccountNumber!
  date: IsoDate!
}

type Mutation {
  """Create an unapproved salary payment, ready for approval in Folio."""
  registerSalaryPayment(input: RegisterSalaryPaymentInput!): RegisterSalaryPaymentReply!

  """
  Allows sending emails with attachments. Return value represents the number of
  emails sent.
  
  Each email will cap out at 19mb in attachments, and any single attachment
  larger than 19mb will be rejected.
  """
  sendEmail(emailInput: CustomEmailInput!): Int!

  """
  Register a payment for approval. A human must confirm the payment in Folio's
  UI before it can go through.
  To be used by accounting systems.
  """
  registerPayment(input: RegisterPaymentInput!): RegisterPaymentReply!

  """
  Disables the integration client. This means revoking the tokens and user
  consent that was issued when the user enabled the integration. This is
  essentially a "self destruct". After issuing this call, no more calls with
  the credentials are allowed.
  """
  disableIntegration: DisableIntegrationReply!

  """
  Tell Folio that the accounting system and its user has reconciled (avstemt)
  the given account up to and including the date.
  """
  setAccountReconciliationDate(accountNumber: AccountNumber!, date: IsoDate!): SetReconciliationReply!

  """
  Mark a single activity as complete from external system.
  Prevents activities to be in the 'mangler noe' tab when
  it is marked complete outside Folio.
  """
  setActivityComplete(
    """Unique ID of an activity"""
    id: UUID!

    """Flag indicating booked/done status"""
    complete: Boolean!
  ): Boolean!
}

type GeoLocation {
  lat: Float!
  lng: Float!
}

type ReceiptImages {
  croppedUrl: URL
}

enum LedgerCategoryItemRequirement {
  Receipt
  Participants
  Purpose
}

"""
The ledger account name and number for a category in Folio. There are account
numbers for Folio, as well as a number of accounting systems. In some cases
a category maps to different ledger accounts in different systems
For example:
The category "Lunsj" in Folio maps to the ledger account number \`6800\`, except
for when using Fiken, where it maps to \`6801\`.
"""
type LedgerAccount {
  code: Int! @deprecated(reason: "Use one of the specific code fields instead")
  name: String!
  folio: Int!
  fiken: Int!
  uniEconomy: Int!
  tripletex: Int!
  powerOfficeGo: Int!
  vismaEAccounting: Int!
}

type LedgerCategoryItem {
  id: ID!
  title: String!
  subtitle: String
  account: LedgerAccount!
  requirements: [LedgerCategoryItemRequirement!]!
  synonyms: [String!]!
  parent: LedgerCategory!
  hidden: Boolean!
  vat: VatData!
}

type LedgerCategory {
  id: ID!
  title: String!
  subtitle: String
  items: [LedgerCategoryItem!]!
}

type Merchant {
  id: UUID!
  name: String!
  address: String
  postalCode: String
  city: String
  countryCode: CountryCode
  organizationNumber: OrganizationNumber
  geoLocation: GeoLocation
  googlePlacesID: String

  """Has been checked by a human"""
  verified: Boolean
}

"""
Information about the bank accounts in the organization, when used in the
context of exports. These are the 'authoritative' versions of the bank accounts
in the organization. The purpose of this is that when exporting, there should
be a single bank account number representing every card bank account. In the
future, this may apply to other account types as well.
"""
type ExportAccounts {
  operationalAccount: OrganizationAccount!

  """The authoritative tax account, if the org has a tax account."""
  taxAccount: OrganizationAccount

  """The authoritative savings account, if the org has a savings account."""
  savingsAccount: OrganizationAccount

  """
  For exports we only show a single account rather than every individual card
  account.
  """
  cardAccount: OrganizationAccount!
}

enum ActivityPartyKind {
  paidFrom
  paidTo
}

type GenericBankAccount implements BankAccount {
  accountNumber: AccountNumber!
  bankName: String
}

"""
The ledger account numbers for Folio, and mapped to accounting systems. This
is useful in cases where an accounting system uses a different chart of accounts
(kontoplan) than that in Folio.
"""
type LedgerAccountNumber {
  folio: Int!
  fiken: Int!
  uniEconomy: Int!
  tripletex: Int!
  powerOfficeGo: Int!
  vismaEAccounting: Int!
}

type VatData {
  name: String!
  code: Int! @deprecated(reason: "Use `codeString`")
  codeString: String!
  rate: String!
}

type ActivityLedgerAccount {
  accountName: String!
  accountNumber: LedgerAccountNumber!
  vat: VatData!
}

type ActivityPartyStrings {
  """
  The best guess at the name of the party, by looking at accounts, merchant info,
  OCR lookup and text fields on the raw event. If there is no information
  about the party, returns `null`.
  
  | Party type                                      | Result         |
  |-------------------------------------------------|----------------|
  | Ola's card account in MyOrg Inc                 | `"MyOrg Inc"`  |
  | Organization's operational account              | `"MyOrg Inc"`  |
  | Other organization called "Vendor Inc"          | `"Vendor Inc"` |
  | Other organization we have no information about | `null`         |
  """
  partyName: String

  """
  If the party is the organization of the API user, and we know which account
  was used, returns the account type. Otherwise, the same as the `name` field.
  If there is no information about the party, returns `null`.
  
  | Party type                                      | Result          |
  |-------------------------------------------------|-----------------|
  | Ola's card account in MyOrg Inc                 | `"kortkonto"`   |
  | Organization's operational account              | `"driftskonto"` |
  | Other organization called "Vendor Inc"          | `"Vendor Inc"`  |
  | Other organization we have no information about | `null`          |
  """
  accountTypeOrPartyName: String

  """
  If the party is the organization of the API user, and we know which account
  was used, returns the account name. Otherwise, the same as the `name` field.
  If there is no information about the party, returns `null`.
  
  | Party type                                      | Result          |
  |-------------------------------------------------|-----------------|
  | Ola's card account in MyOrg Inc                 | `"Ola"`         |
  | Organization's operational account              | `"driftskonto"` |
  | Other organization called "Vendor Inc"          | `"Vendor Inc"`  |
  | Other organization we have no information about | `null`          |
  """
  accountNameOrPartyName: String
}

"""
One part of a transaction, either the one paying or the one getting paid.
"""
type ActivityParty {
  """The amount of money that moved, in Norwegian krone"""
  nokAmount: AmountInfo!

  """The amount of money that moved, in the currency it was moved"""
  currencyAmount: AmountInfo!
  role: ActivityPartyKind!

  """
  If no account information is known yet, this is null. For accounts
  belonging to the organization, it contains the complete account information.
  For accounts that don't belong to the org, only the account number and our
  best guess at an account name is available.
  """
  account: BankAccount

  """The merchant information about the party, if available."""
  merchant: Merchant

  """If the party used a card, card info is here."""
  card: Card

  """The transaction of this party."""
  activity: Activity!

  """If a ledger account has been selected, it's here."""
  ledgerAccount: ActivityLedgerAccount

  """Human readable strings about the activity appropriate for display."""
  strings: ActivityPartyStrings!
}

enum OrganizationActivityRole {
  paidFrom
  paidTo
  paidFromAndTo
}

"""Representation of an amount, and the currency of the amount."""
type AmountInfo {
  """
  The amount as an unsigned number, as a string with decimals in a format
  suitable to parse as a floating point number. The number of decimals will
  always match `minorUnitSize`. For example:
  
  - 452 NOK: `452.00`
  - 1 NOK: `1.00`
  - 1.99 NOK: `1.99`
  - 5435 YEN: `5435`
  - 10.5 TND: `10.500`
  """
  asNumericString: String!

  """
  The amount as an unsigned number in the minor unit of the currency. The
  amount `49.90` in NOK is represented as `499000`. That is, the amount in øre.
  See https://en.wikipedia.org/wiki/ISO_4217 for more information about minor
  units.
  """
  asMinorUnit: SafeInt!

  """The amount as an unsigned floating point number."""
  asNumber: Float!

  """Absolute version of `asNumericString`."""
  asAbsoluteNumericString: String!

  """Absolute version of `asMinorUnit`."""
  asAbsoluteMinorUnit: SafeInt!

  """Absolute version of `asNumber`."""
  asAbsoluteNumber: Float!

  """Flag indicating if the amount is negative."""
  isNegative: Boolean!

  """
  Flag to tell if the amount is in Norwegian krone. Useful as a shorthand to
  avoid doing comparisons with numericCode/alphabeticCode to check if we're in
  the "native" Folio currency.
  """
  isNok: Boolean!

  """
  The "minor unit" size of the currency. That is, how many digits are used to
  represent fractions of the currency. For NOK, it is `2` because an øre
  amount is represented by two digits, 0-99.
  """
  minorUnitSize: Int!

  """
  The numeric currency code from https://en.wikipedia.org/wiki/ISO_4217 .
  """
  numericCode: NumericCurrencyCode!

  """
  The alphabetic currency code from https://en.wikipedia.org/wiki/ISO_4217 .
  """
  alphabeticCode: AlphabeticCurrencyCode!
}

"""
A movement of funds involving one or more accounts belonging to an organization.
For example when:

- Using a Folio card at a physical terminal.
- Using a Folio card online.
- Paying an invoice.
- Receiving payment.
- Moving funds between the organizations accounts.

Transactions always have two parties: a `debtor` and `creditor` side. The party
that pays and receives funds. In the case of internal transfers, both parties
are present, and are in the same organization.

Transactions can mutate from the point they are created until the time they
are completed. Mutations are caused by more information coming from banking
systems, such as daily transfers and synchronization with credit card issuers.
"""
type Activity {
  """Unique ID of an activity"""
  id: UUID!

  """
  Indicate if money was paid to the org, paid from the org or moved within the
  org.
  """
  role: OrganizationActivityRole!

  """
  The amount of money that moved in our out of the organization. If this is an
  internal transfer, the amount is 0. The `paidFrom` and `paidTo` objects
  contain the amounts involved in the activity for each direction.
  """
  nokAmount: AmountInfo!

  """
  Same as `nokAmount` but in the currency that was used for the activity.
  """
  currencyAmount: AmountInfo!

  """The timestamp when the activity was started."""
  startedAt: IsoUtcDateTime!

  """The date on which the movement of funds was completed."""
  bookedAt: IsoDate

  """True if the funds have finished moving."""
  booked: Boolean!

  """The party to the activity that sent funds."""
  paidFrom: ActivityParty!

  """The party to the activity that received funds."""
  paidTo: ActivityParty!

  """The organization this activity belongs to."""
  organization: Organization!

  """
  If a card was involved in the activity, it's available here, as well as via
  the debtor or creditor."
  """
  card: Card

  """
  If a merchant is involved, it will be here as well as via the debtor or
  creditor.
  """
  merchant: Merchant

  """List of receipts attached as documentation to the event."""
  receipts: [Receipt!]!

  """The selected category for the activity."""
  accountingCategoryInfo: ActivityLedgerCategoryInfo!

  """Human readable strings appropriate for display."""
  strings: ActivityStrings!

  """The URL where the voucher PDF document can be downloaded from."""
  voucherDownloadUrl: URL!

  """
  Any requirements for the activity to be considered complete. Always defined,
  with the only requirement being `Category` if one isn't selected.
  """
  requirements: ActivityRequirements!

  """
  True when the event is booked, there is a category selected, and all the
  requirements for the category is fulfilled.
  """
  completed: Boolean!

  """The associated payment object."""
  payment: PaymentInfo

  """
  The salary payment this activity belongs to. `null` if activity is not part of a salary payment.
  """
  salaryPayment: SalaryPayment

  """
  Flag indicating if the activity was triggered by interacting with a physical
  payment terminal.
  """
  physicalTerminal: Boolean!

  """Flag indicating if the event was created outside of Folio or not."""
  external: Boolean!

  """For internal use."""
  unstable_annotations: ActivityAnnotations!

  """
  Null if the transaction does not exist. This will turn into an enum instead
  of the integer value at some point.
  """
  unstable_transactionType: Int

  """Will be null if agent does not have access."""
  unstable_debugInformation: ActivityDebugInformation

  """The MCC of the activity if there was one."""
  unstable_mcc: String

  """External ID provided when creating a payment."""
  externalId: ID

  """
  Flag that is true if this activity is a leg of an internal transfer that
  should be ignored by the consumer.
  This is a temporary workaround that will be removed as soon as the API stops
  notifying consumers about activities they should not need to know about.
  """
  unstable_isInternalTransferLeg: Boolean!
}

type ActivityDebugInformation {
  """Raw data from the underlying bank infrastructure."""
  rawBankInformation: String!
}

type ActivityRequirements {
  """The number of requirements that have been met for the event."""
  metRequirementCount: Int!

  """The number of requirements that must be met for the event."""
  totalRequirementCount: Int!

  """All the requirements for the event."""
  allRequirements: [ActivityRequirement!]!

  """The requirements for the event that have not been met."""
  unmetRequirements: [ActivityRequirement!]!

  """Flag indicating if the requirements of the event have been met."""
  allRequirementsMet: Boolean!
}

enum ActivityRequirement {
  Category
  Participants
  Purpose
  Receipt
}

type ActivityStrings {
  description: String!
  rawDescription: String
  unstable_transactionDescription: String!
  unstable_message: String
  unstable_kid: KidNumber
  unstable_transactionSubtitle: String
}

type ActivityAnnotations {
  note: ActivityAnnotation
  participants: ActivityAnnotation
  purpose: ActivityAnnotation
  receiptLost: ActivityAnnotation
  noReceiptNeeded: ActivityAnnotation
}

type ActivityAnnotation {
  id: UUID!
  body: String!
  addedAt: IsoUtcDateTime!
  addedBy: Agent
}

input CustomEmailInput {
  from: String!
  to: String!
  subject: String!
  attachments: [EmailAttachment!]!
}

input EmailAttachment {
  url: URL!
  filename: String
}

input PaymentAttachment {
  """
  A public URL (i.e. needs no authentication) the attachment can be fetched
  from.
  """
  url: URL!
  filename: String

  """
  If neither `url` nor `filename` have a file extension `mime` can be inferred
  from, use this field.
  """
  mime: String
}

"""
The error code from backend services. GraphQLErrors with an `extension` with
`code` equal to `BackendError`, there will be an `errors` array containing
objects where the `code` is one of the ones in this enum.
"""
enum BackendErrorCode {
  Unspecified
  AlreadyExists
  InvalidParameter
  InternalError
  NotFound
  AccessDenied
  Forbidden
  CardActivityAccountError
  BadTokenSignature
  Timeout
  Cancelled
  InvalidTokenFormat
  TokenExpired
  TokenNoLongerValid
  IncorrectTokenType
  DisabledAgent
  InvalidEmailAddress
  PasswordProtectedPDF
  InvalidPDF
  BankIDSessionAbortedByUser
  BankIDSessionInvalidated
  BankIDSessionTimeout
  BankIDSessionBadMobileOrBirthDate
  BankIDSessionMobileNumberAlreadyInUse
  BankIDSessionMobileOperatorFailure
  BankIDMobileCertificateBlocked
  BankIDSessionGenericError
  CardBadEncryptedPinData
  CardDeleted
  PaymentInsufficientFunds
  PaymentAlreadyAuthorised
  PaymentAlreadyCompleted
  PaymentAlreadyInProcess
  PaymentIncorrectUserSigned
  PaymentOutOfSync
  PaymentAccountUnauthorized
  PaymentCreditorAccountClosed
  PaymentNoKIDAgreement
  PaymentNotTreasuryAccount
  PaymentInvalidKID
  PaymentAccountBlocked
  PaymentKIDRequired
  BulkPaymentPartiallyUnapproved
  PaymentInvalidCreditorAccount
  PaymentCreditorAccountBlocked
  PaymentCreditorAccountFailsAML
  ENKIsAlreadySPVCustomer
  OnboardingAMLFailed
  SPVAgentNotFound
  SPVGenericError
  OAuthClientNotFound
  OAuthUnauthorizedClient
  OAuthInvalidScope
  OAuthInvalidGrant
  OAuthBadRedirectURL
}
Folio AS, 2020