NAV Navbar
cURL

Overview

Environments

Environment Base URL
Production https://api.jenji.io
Unstable https://api-test.jenji.io

Authentication

The Jenji API uses HTTP Basic Authentication.

Using an organisation API Key

curl -X GET "https://api-test.jenji.io/s/test" \
     -u API_USER_ID:SECRET_KEY

With every request made to the API you must provide your API user ID and key as basic auth credentials.

Using a bookkeeper API Key

curl -X GET "https://api-test.jenji.io/s/test" \
     -u API_USER_ID:SECRET_KEY:API_BK

With every request made to the API you must provide your API user ID, secret key and key type as basic auth credentials.

Rate limits

We have a rate limit in place in order to provide a fair response time to all our API users.

API calls will be rate limited after 3 requests per second or 120 requests per minutes, whichever happens first. All requests count towards the rate limit.

Data model

The data model of Jenji is articulated around two major domains of expense management:

Both domains may interact together, for instance when an organization delegates the accounting of its expenses to a bookkeeper.

Organization Domain

An organization is an operating company, for which we want to track expenses. It is structured into a hierarchy of organization groups, each group representing an operational team of the company. The top group of the hierarchy is the default system root group.

Members of the organization, such as sales representatives and managers, may gain access to the organization as organization users, to act at the many steps of the workflow of expense management. They belong to a particular group, thus inheriting security and access policies defined for that group.

Some members may create expenses to record their spending and request reimbursement. Expenses may be of different types:

Expenses may also be grouped together in an expense request (if the option has been enabled), allowing for a more old school validation workflow.

The expense, aside from its various header data and amounts, is also enriched with analytic data, which can be customized per organization and per group. Standard analytic data include a category, such as "meal" or "travel", a payment method which was used to pay for the expense (like a credit card), or even a vehicle in case of mileage expenses.

Organization may also define their own analytic drivers, with custom fields, which form a powerful way to mark an expense for accurate accounting repartition. Custom fields may be of different types, for instance numbers, lists, dates or places, and be made available to the end users depending on scoping conditions: expenses, expense requests, users, groups and advances.

Finally, the process of expense management may be standard, with simple phases of expense creation, checking, validation, accounting and reimbursement, or be completely customized for an organization, with a dedicated workflow and user profiles authorized to act on specific steps of that workflow.

Bookkeeper Domain

A bookkeeper is an accounting company, which manages the accounts of client companies, such as liberal professionals.

Like an organization, a bookkeeper is structured into a hierarchy of bookkeeper groups topped by a default system root group, each group representing an operational team of the bookkeeper. Team members, a.k.a. bookkeeper users, belong to only one group, inheriting security and access policies defined for that group.

An organization may delegate the accounting of its expenses to a bookkeeper, in which case it becomes a client (or account) of that bookkeeper. In particular cases, bookkeepers may also delegate part of their activity to another bookkeeper, which then becomes their master bookkeeper.

Support

You can contact us at support-api@jenji.io.

Organizations

Set of methods to create, update or view organizations. These methods may only be used by an organization, by its bookkeeper or by the master bookkeeper of its bookkeeper.

List available organization summaries

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
    "name" : "Demo organization",
    "plan" : "ENTERPRISE",
    "createdBy" : "demo@domain.com",
    "createdAt" : "2021-12-15T15:15:00.000000999Z",
    "masterCurrency" : "EUR",
    "masterCountry" : "FR",
    "masterLanguage" : "fr",
    "masterDistanceUnit" : "KM"
  } ]
}

Return a list of organization summaries that the authenticated user can have access to.

Request

GET /api/org/v1/organizations

Response body

The list of available organizations.

field type description
data OrganizationSummary[]
data[].id String Unique identifier of the Organization in Jenji (UUID).
data[].name String Name of the organization, usually the name of the company.
data[].plan String Commercial plan of the organization. One of:
  • FREE: also known as SOLO plan, this is the forever-free plan for Jenji, with restricted features.
  • PRO: standard paying plan, with most features.
  • ENTERPRISE: custom paying plan for enterprises, with custom system integrations.
data[].createdBy String Medium through which the organization was created (backend, mobile application...).
data[].createdAt OffsetDateTime Timestamp of the creation of the organization.
data[].masterCurrency String The reporting currency of the organization. Expenses may be expressed in local currencies, different from the organization currency, but amounts are always converted and reported to the currency of the organization.
data[].masterCountry String The reporting country of the organization.
data[].masterLanguage String The reporting language of the organization.
data[].masterDistanceUnit DistanceUnit Distance unit for the organization. Default is km.

View an organization

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a" \
     -u API_USER_ID:SECRET_KEY \
{
  "id" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "name" : "Demo organization",
  "plan" : "ENTERPRISE",
  "createdBy" : "demo@domain.com",
  "createdAt" : "2021-02-19T09:51:20.000000987Z",
  "masterCurrency" : "EUR",
  "masterCountry" : "FR",
  "masterLanguage" : "fr",
  "availableLanguages" : [ "en", "fr" ],
  "categories" : [ {
    "id" : "lunch",
    "disabled" : false,
    "labelsPerLanguage" : {
      "en" : "Lunch",
      "fr" : "Repas"
    },
    "order" : 0
  } ],
  "groups" : [ {
    "id" : "root",
    "internalId" : "000",
    "name" : "Demo organization"
  }, {
    "id" : "e18fdcfd-aa3a-4ba4-98fa-d3441d0510e8",
    "internalId" : "001",
    "name" : "Sub group",
    "parentGroupId" : "root"
  } ],
  "userCustomFields" : [ {
    "key" : "agency",
    "type" : "STRING",
    "required" : true,
    "labelsPerLanguage" : {
      "en" : "Agency",
      "fr" : "Agence"
    },
    "order" : 0
  } ]
}

Return the details of an organization.

Request

GET /api/org/v1/organizations/{organizationId}

Response body

The details of the specified organization.

See Organization

Edit an organization

curl -X PATCH "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "name" : "New demo name",
              "masterLanguage" : "en",
              "masterCurrency" : "GBP",
              "masterCountry" : "UK"
            }'
{
  "id" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "name" : "New demo name",
  "plan" : "ENTERPRISE",
  "createdBy" : "demo@domain.com",
  "createdAt" : "2021-02-19T09:51:20.000000987Z",
  "masterCurrency" : "UK",
  "masterCountry" : "GBP",
  "masterLanguage" : "en",
  "availableLanguages" : [ "en", "fr" ],
  "categories" : [ {
    "id" : "lunch",
    "disabled" : false,
    "labelsPerLanguage" : {
      "en" : "Lunch",
      "fr" : "Repas"
    },
    "order" : 0
  } ],
  "groups" : [ {
    "id" : "root",
    "internalId" : "000",
    "name" : "Demo organization"
  }, {
    "id" : "8df8a077-8cfd-437c-9899-b996fbdeab7d",
    "internalId" : "001",
    "name" : "Sub group",
    "parentGroupId" : "root"
  } ],
  "userCustomFields" : [ {
    "key" : "agency",
    "type" : "STRING",
    "required" : true,
    "labelsPerLanguage" : {
      "en" : "Agency",
      "fr" : "Agence"
    },
    "order" : 0
  } ]
}

Patch the organization value, only non null value will be taken into account.

Request

PATCH /api/org/v1/organizations/{organizationId}

Request body

Patch organization data.

field type description
name String Organization name

Empty or null value will be ignored

masterLanguage String Organization default language.

Empty string will clear the field, null will be ignored.

masterCurrency String Organization default currency for expenses

Empty string will clear the field, null will be ignored.

masterCountry String Organization default country

Empty string will clear the field, null will be ignored.

Response body

An organization is an operating company, for which we want to track expenses. Members of the organization, such as sales representatives, managers, accountants, may gain access to the organization as organization users, to act at the many steps of the workflow of expense management.

See Organization

Create a new group

curl -X POST "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/groups" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "name" : "Sub group 2",
              "parentGroupId" : "a3b7e233-2e19-42dd-a299-ebbe5e184f27",
              "internalId" : "007"
            }'
{
  "id" : "7a2c7c61-5ab7-4e11-b3ad-479d54d29d20",
  "internalId" : "Sub group 2",
  "name" : "Sub group 2",
  "parentGroupId" : "a3b7e233-2e19-42dd-a299-ebbe5e184f27",
  "createdAt" : "2021-02-19T14:43:59.000000999Z",
  "updatedAt" : "2021-02-19T14:43:59.000000999Z"
}

Add a new group to an organization. The caller may specify a parent group to form a hierarchy, or leave the parent null, in which case the group will be created as a direct child of the root group.

Request

POST /api/org/v1/organizations/{organizationId}/groups

Request body

Data used to create the new group.

field type description
name String Mandatory. The name of the organization group, e.g. the designation of the team.
parentGroupId String Optional. The parent group of the group to be created. If left empty, then the group parent is automatically set to the organization root group.
internalId String The code of the group, i.e. team, as known in the organization information system.

Response body

The newly-created group. To see the entire hierarchy, make a GET on the organization itself.

See OrganizationGroup

Update group

# Update name and internal id
curl -X PATCH "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/groups/7a2c7c61-5ab7-4e11-b3ad-479d54d29d20" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "name" : "Sub group OSS",
              "internalId" : "117"
            }'
{
  "id" : "7a2c7c61-5ab7-4e11-b3ad-479d54d29d20",
  "internalId" : "Sub group OSS",
  "name" : "Sub group OSS",
  "parentGroupId" : "a3b7e233-2e19-42dd-a299-ebbe5e184f27",
  "createdAt" : "2021-02-19T14:43:59.000000999Z",
  "updatedAt" : "2021-02-21T09:26:41.000000999Z"
}
# Update parent group and clear internal id
curl -X PATCH "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/groups/7a2c7c61-5ab7-4e11-b3ad-479d54d29d20" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "parentGroupId" : "root",
              "internalId" : ""
            }'
{
  "id" : "7a2c7c61-5ab7-4e11-b3ad-479d54d29d20",
  "name" : "Sub group 2",
  "parentGroupId" : "root",
  "createdAt" : "2021-02-19T14:43:59.000000999Z",
  "updatedAt" : "2021-02-21T09:26:41.000000999Z"
}

Update the values of the group's fields.
The values of group already defined but not in the request will not be modified or deleted.

Request

PATCH /api/org/v1/organizations/{organizationId}/groups/{groupId}

Path variables

parameter type required description
groupId String true

Request body

Custom fields values to update.

field type description
name String The name of the group, e.g. the designation of the team. Can not be an empty string.

If null, name is not updated

parentGroupId String The parent group of the group to be created. If empty string, then the group parent is automatically set to the organization root group.

If null, parent is not updated

internalId String The code of the group, i.e. team, as known in the organization information system. Pass an empty string to clear the value.

If null, internal id is not updated

Response body

The updated group. To see the entire hierarchy, make a GET on the organization itself.

See OrganizationGroup

Update group custom field values

Update the values of the group's custom fields.
The values of group custom fields already defined but not in the request will not be modified or deleted.
A group custom field value in the request that does not already exist will be created.
All group custom fields in the request must have a definition already set.

Request

PATCH /api/org/v1/organizations/{organizationId}/groups/{groupId}/custom-fields

Path variables

parameter type required description
groupId String true

Request body

Custom fields values to update.

field type description
customFieldsValues Map<String,Object> Mandatory. The map of custom fields values to update.

Response body

The updated group. To see the entire hierarchy, make a GET on the organization itself.

field type description
customFieldsValues Map<String,?> All group custom field values after update

List all communications

List all the communications of the organization.

Request

GET /api/org/v1/organizations/{organizationId}/communications

Response body

field type description
data OrganizationCommunication[]
data[].id String Unique identifier of the communication in Jenji (UUID).
data[].code String Code freely defined by a manager to identify a specific communication in a human readable way.
data[].groupId String Identifier of the organization group for which the communication has been defined.
data[].messagesPerLanguage Map<String,String> The messages of the communication, per language, as displayed to front clients (web application, mobile applications).
data[].level String Level of the communication : INFO, WARNING, ERROR, SUCCESS.
data[].startDate OffsetDateTime Start date of the communication. If null, the communication is considered as started.
data[].endDate OffsetDateTime End date of the communication. If null, the communication is considered still running.
data[].updatedAt OffsetDateTime Timestamp of the last modification of the communication.

Create new communication

Create a new communication for an organization group.

Request

POST /api/org/v1/organizations/{organizationId}/communications

Request body

Create a new organization communication.

field type description
code String Mandatory. Code freely defined by a manager to identify a specific communication in a human readable way.
groupId String Mandatory. Identifier of the organization group for which the communication has been defined.
messagesPerLanguage Map<String,String> Mandatory. The messages of the communication, per language, as displayed to front clients (web application, mobile applications).
level String Mandatory. Level of the communication : INFO, WARNING, ERROR, SUCCESS.
startDate OffsetDateTime Optional. Start date of the communication. If null, the communication is considered as started.
endDate OffsetDateTime Optional. End date of the communication. If null, the communication is considered still running.

Response body

Any business message defined by an organization group manager to inform all users of that group. ex: 'Please enter all your expenses before the 25th of the month to be reimbursed'.

See OrganizationCommunication

Update existing communication

Update an existing communication for an organization group.

Request

PUT /api/org/v1/organizations/{organizationId}/communications/{communicationId}

Path variables

parameter type required description
communicationId String true

Request body

Update an existing communication.

field type description
code String Mandatory. Code freely defined by a manager to identify a specific communication in a human readable way.
groupId String Mandatory. Identifier of the organization group for which the communication has been defined.
messagesPerLanguage Map<String,String> Mandatory. The messages of the communication, per language, as displayed to front clients (web application, mobile applications).
level String Mandatory. Level of the communication : INFO, WARNING, ERROR, SUCCESS.
startDate OffsetDateTime Optional. Start date of the communication. If null, the communication is considered as started.
endDate OffsetDateTime Optional. End date of the communication. If null, the communication is considered still running.

Response body

Any business message defined by an organization group manager to inform all users of that group. ex: 'Please enter all your expenses before the 25th of the month to be reimbursed'.

See OrganizationCommunication

Delete a communication

Delete an existing communication.

Request

DELETE /api/org/v1/organizations/{organizationId}/communications/{communicationId}

Path variables

parameter type required description
communicationId String true

List user activities

List activity for all users of an organization, on the given time period.

Request

GET /api/org/v1/organizations/{organizationId}/user-activities

Query parameters

parameter type required description
from LocalDate true Start date (format: YYYY-MM-DD).
to LocalDate true End date, not inclusive (format: YYYY-MM-DD).

Response body

List of users activities for an organization matching the search criteria.

field type description
data DailyUserActivity[]
data[].userId String The user identifier. Format: UUID v4.
data[].day String The day of activity. Format: YYYY-MM-DD.
data[].organizationId String The organization identifier. Format: UUID v4.
data[].created int The number of expenses created that day. Increased as soon as the user creates a standard, mileage or allowance expense.
data[].checked int In organizations with the compliance step enabled, incremented as soon as the user marks an expense as 'compliant' or 'not compliant'. For organizations with a custom expense workflow, incremented when the user performs an intermediary validation step.
Only possible for users with expense verification rights or equivalent profiles.
data[].decided int Incremented as soon as the user marks an expense as accepted or rejected. For organizations with a custom expense workflow, incremented when the user performs the final validation step on an expense.
Only possible for users with expense validation rights or equivalent profiles.
data[].accounted int Incremented when an accounting export is marked as 'accounted'. Every expense in the export increments this counter by 1.
Only possible for users with accounting rights.
data[].paid int Incremented when a payroll export is marked as 'reimbursed'. Every expense in the export increments this counter by 1.
Only possible for users with accounting rights.
data[].deleted int Incremented as soon as the user changes the state of an expense to 'DELETED'.
Since Jenji only performs logical deletions, multiple delete/undelete operations on a same expense will increment this counter multiple times.
data[].ignored int The number expense actions that would usually be billed but are ignored because of special organization rules. This field can safely be ignored if no such rules have been contractually defined.

Org. base customization

Set of methods to create, update or view organization categories.

List categories

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/categories" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "lunch",
    "disabled" : false,
    "labelsPerLanguage" : {
      "en" : "Lunch",
      "fr" : "Repas"
    },
    "order" : 0
  }, {
    "id" : "taxi",
    "disabled" : true,
    "labelsPerLanguage" : {
      "en" : "Taxi",
      "fr" : "Taxi"
    },
    "order" : 99
  } ]
}
curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/categories?disabled=false" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "lunch",
    "disabled" : false,
    "labelsPerLanguage" : {
      "en" : "Lunch",
      "fr" : "Repas"
    },
    "order" : 0
  } ]
}

Fetch the list of expense categories

Request

GET /api/org/v1/organizations/{organizationId}/categories

Query parameters

parameter type required description
disabled Boolean false filter categories on disabled attribute: using false will return only active categories

Response body

field type description
data Category[]
data[].id String Identifier of the category. This is usually a code unique within the organization, either a standard code for a Jenji category, or a custom code for a custom category.
data[].disabled Boolean The category may be disabled, i.e. is not usable on new expenses. Previous expenses which reference this category may still use it.
data[].notSelectable Boolean The category is still valid, but not usable.
data[].labelsPerLanguage Map<String,String> The labels of the category, per language, as displayed to front clients (web application, mobile applications). Organization which define custom categories are encouraged to define labels for all the languages they manage.
data[].ocrMappedStandardCategories String[] List of standard category codes to map onto the custom category, when our AI-based agent analyzes a receipt and derives a standard category which has been replaced by a custom category by the organization.
data[].order Integer Order of the category for front clients.
data[].parentCategoryId String Categories may be hierarchical; child categories reference a parent category.
data[].iconId String The identifier of the icon used to display the category in front clients.
data[].colorId String The identifier of the color used to display the category in front clients.
data[].scopeCondition ScopeCondition Allow to manage the visibility of the category, using advanced conditions

Update all categories

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/categories" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '[ {
              "id" : "gift",
              "disabled" : false,
              "labelsPerLanguage" : {
                "en" : "Daily lunch",
                "fr" : "Daily lunch"
              },
              "order" : 0
            } ]'
{
  "data" : [ { }, {
    "id" : "lunch",
    "disabled" : true,
    "order" : 99
  }, {
    "id" : "taxi",
    "disabled" : true,
    "labelsPerLanguage" : {
      "en" : "Taxi",
      "fr" : "Taxi"
    },
    "order" : 99
  } ]
}

Update the full list of categories.

Categories not included in the body (using the id attribute) will be disabled with an order putting them at the end of list. Disabled categories will be returned in the answer.

Request

PUT /api/org/v1/organizations/{organizationId}/categories

Request body

new list of categories to apply

field type description
id String Identifier of the category. This is usually a code unique within the organization, either a standard code for a Jenji category, or a custom code for a custom category.
disabled Boolean The category may be disabled, i.e. is not usable on new expenses. Previous expenses which reference this category may still use it.
notSelectable Boolean The category is still valid, but not usable.
labelsPerLanguage Map<String,String> The labels of the category, per language, as displayed to front clients (web application, mobile applications). Organization which define custom categories are encouraged to define labels for all the languages they manage.
ocrMappedStandardCategories String[] List of standard category codes to map onto the custom category, when our AI-based agent analyzes a receipt and derives a standard category which has been replaced by a custom category by the organization.
order Integer Order of the category for front clients.
parentCategoryId String Categories may be hierarchical; child categories reference a parent category.

Only one category level is authorized

iconId String The identifier of the icon used to display the category in front clients.
colorId String The identifier of the color used to display the category in front clients.
scopeCondition ScopeCondition Allow to manage the availability of the category, using advanced conditions

Response body

The organization categories after update.

field type description
data Category[]
data[].id String Identifier of the category. This is usually a code unique within the organization, either a standard code for a Jenji category, or a custom code for a custom category.
data[].disabled Boolean The category may be disabled, i.e. is not usable on new expenses. Previous expenses which reference this category may still use it.
data[].notSelectable Boolean The category is still valid, but not usable.
data[].labelsPerLanguage Map<String,String> The labels of the category, per language, as displayed to front clients (web application, mobile applications). Organization which define custom categories are encouraged to define labels for all the languages they manage.
data[].ocrMappedStandardCategories String[] List of standard category codes to map onto the custom category, when our AI-based agent analyzes a receipt and derives a standard category which has been replaced by a custom category by the organization.
data[].order Integer Order of the category for front clients.
data[].parentCategoryId String Categories may be hierarchical; child categories reference a parent category.
data[].iconId String The identifier of the icon used to display the category in front clients.
data[].colorId String The identifier of the color used to display the category in front clients.
data[].scopeCondition ScopeCondition Allow to manage the visibility of the category, using advanced conditions

Update one category

Update a single category.

Disabling a category will disable all sub categories

Request

PUT /api/org/v1/organizations/{organizationId}/categories/{categoryId}

Path variables

parameter type required description
categoryId String true id of category to update

Request body

new category values

field type description
disabled Boolean The category may be disabled, i.e. is not usable on new expenses. Previous expenses which reference this category may still use it.
notSelectable Boolean The category is still valid, but not usable.
labelsPerLanguage Map<String,String> The labels of the category, per language, as displayed to front clients (web application, mobile applications). Organization which define custom categories are encouraged to define labels for all the languages they manage.
ocrMappedStandardCategories String[] List of standard category codes to map onto the custom category, when our AI-based agent analyzes a receipt and derives a standard category which has been replaced by a custom category by the organization.
order Integer Order of the category for front clients.
parentCategoryId String Categories may be hierarchical; child categories reference a parent category.

Only one category level is authorized

iconId String The identifier of the icon used to display the category in front clients.
colorId String The identifier of the color used to display the category in front clients.
scopeCondition ScopeCondition Allow to manage the availability of the category, using advanced conditions

Response body

The updated category.

See Category

List payment methods

Fetch the list of expense payment methods

Request

GET /api/org/v1/organizations/{organizationId}/payment-methods

Query parameters

parameter type required description
disabled Boolean false filter payment methods on disabled attribute: using false will return only active payment methods

Response body

field type description
data PaymentMethod[]
data[].id String Unique identifier of the payment method in Jenji (UUID).
data[].label String The label of the payment method, to help the user select the appropriate method when creating the expense.
data[].labelsPerLanguage Map<String,String> The labels of the payment method, per language, as displayed to front clients (web application, mobile applications).
data[].code String The code of the payment method, available in various exports.
data[].reimbursable Boolean Whether any expense made with this payment is reimbursable. A company credit card, for instance, would not incur reimbursable expenses, while a personal credit card would require reimbursements.
data[].dissociated Boolean Whether the payment method is dissociated.
data[].disabled Boolean Whether the payment method is now disabled, i.e. may not be used on new expenses.
data[].transactionProvider String A payment method may be associated with a transaction provider, such as a bank. Jenji offers many integration features with existing banks, whereby an organization may allow Jenji to retrieve bank transactions from its bank, so as to automatically reconcile an expense with a matching bank transaction.

Update all payment methods

Update the full list of payment methods. Update existing payment method matching the id attribute, create the new ones.

Payment methods not included in the body (using the id attribute) will be disabled with an order putting them at the end of list. Disabled payment methods will be returned in the answer.

Request

PUT /api/org/v1/organizations/{organizationId}/payment-methods

Request body

new list of payment methods to apply

field type description
id String Unique identifier of the payment method in Jenji (UUID). If null, a random UUID will be generated.
labelsPerLanguage Map<String,String> The labels of the payment method, per language, as displayed to front clients (web application, mobile applications).
code String The code of the payment method, available in various exports.
reimbursable Boolean Whether any expense made with this payment is reimbursable. A company credit card, for instance, would not incur reimbursable expenses, while a personal credit card would require reimbursements.
disabled Boolean Whether the payment method is now disabled, i.e. may not be used on new expenses.

Response body

The organization payment methods after update.

field type description
data PaymentMethod[]
data[].id String Unique identifier of the payment method in Jenji (UUID).
data[].label String The label of the payment method, to help the user select the appropriate method when creating the expense.
data[].labelsPerLanguage Map<String,String> The labels of the payment method, per language, as displayed to front clients (web application, mobile applications).
data[].code String The code of the payment method, available in various exports.
data[].reimbursable Boolean Whether any expense made with this payment is reimbursable. A company credit card, for instance, would not incur reimbursable expenses, while a personal credit card would require reimbursements.
data[].dissociated Boolean Whether the payment method is dissociated.
data[].disabled Boolean Whether the payment method is now disabled, i.e. may not be used on new expenses.
data[].transactionProvider String A payment method may be associated with a transaction provider, such as a bank. Jenji offers many integration features with existing banks, whereby an organization may allow Jenji to retrieve bank transactions from its bank, so as to automatically reconcile an expense with a matching bank transaction.

Create a payment method

Create a single payment method.

Request

POST /api/org/v1/organizations/{organizationId}/payment-methods

Request body

new payment method

field type description
labelsPerLanguage Map<String,String> The labels of the payment method, per language, as displayed to front clients (web application, mobile applications).
code String The code of the payment method, available in various exports.
reimbursable Boolean Whether any expense made with this payment is reimbursable. A company credit card, for instance, would not incur reimbursable expenses, while a personal credit card would require reimbursements.
disabled Boolean Whether the payment method is now disabled, i.e. may not be used on new expenses.

Response body

The created payment method.

See PaymentMethod

Update a payment method

Update a single payment method.

Request

PUT /api/org/v1/organizations/{organizationId}/payment-methods/{paymentMethodId}

Path variables

parameter type required description
paymentMethodId String true id of payment method to update

Request body

new payment method values

field type description
id String Unique identifier of the payment method in Jenji (UUID). If null, a random UUID will be generated.
labelsPerLanguage Map<String,String> The labels of the payment method, per language, as displayed to front clients (web application, mobile applications).
code String The code of the payment method, available in various exports.
reimbursable Boolean Whether any expense made with this payment is reimbursable. A company credit card, for instance, would not incur reimbursable expenses, while a personal credit card would require reimbursements.
disabled Boolean Whether the payment method is now disabled, i.e. may not be used on new expenses.

Response body

The updated payment method.

See PaymentMethod

List allowances templates

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/allowance-templates" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "templateId" : "e38200de-81a9-4803-b4c7-edcd24855cfb",
    "labelsPerLanguage" : {
      "en" : "Lunch",
      "fr" : "Repas"
    },
    "total" : 22,
    "currency" : "EUR",
    "country" : "FR",
    "category" : "lunch",
    "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
    "order" : 0,
    "disabled" : false
  }, {
    "templateId" : "fa1ba01f-dd8d-4bb4-981a-8ce4866e3424",
    "labelsPerLanguage" : {
      "en" : "Single night",
      "fr" : "Nuit hotel"
    },
    "total" : 75,
    "currency" : "EUR",
    "country" : "FR",
    "category" : "hotel",
    "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
    "order" : 1,
    "disabled" : true
  } ]
}
curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/allowance-templates?disabled=false" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "templateId" : "0893ddef-74f7-4761-a748-ed09a30c76fb",
    "labelsPerLanguage" : {
      "en" : "Lunch",
      "fr" : "Repas"
    },
    "total" : 22,
    "currency" : "EUR",
    "country" : "FR",
    "category" : "lunch",
    "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
    "order" : 0,
    "disabled" : false
  } ]
}

Fetch the list of allowances templates

Request

GET /api/org/v1/organizations/{organizationId}/allowance-templates

Query parameters

parameter type required description
disabled Boolean false filter templates on disabled attribute: using false will return only active templates

Response body

field type description
data AllowanceTemplate[]
data[].templateId String Template id, value must be passed when creating an allowance expense.
data[].labelsPerLanguage Map<String,String> The labels of the allowance template, per language, as displayed to front clients (web application, mobile applications).
data[].total BigDecimal The total amount of the allowance.
data[].currency String The currency of the total amount. (EUR, USD, ...)
data[].country String The country of the expense. (FR, US, ...)
data[].category String The category of the expense.
data[].paymentMethodId String The identifier of the payment method which was used to pay the expense (for instance a credit card). Payment methods are declared on the groups of the organization.
data[].order int Template order in the front selection list.
data[].disabled Boolean Disable the template, making creation of new expense from it impossible.
data[].requireReceipt Boolean User must add a receipt with the allowance (default false). If no receipt is required, the category icon will be used instead.
data[].creationCondition ScopeCondition Allow to manage the availability of the template for the users, using advanced conditions

Create allowances templates

curl -X POST "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/allowance-templates" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "labelsPerLanguage" : {
                "en" : "Internet",
                "fr" : "Internet"
              },
              "total" : 30,
              "currency" : "EUR",
              "country" : "FR",
              "category" : "other",
              "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
              "disabled" : false
            }'
{
  "templateId" : "48bb29ff-61a6-43f9-9874-504692889555",
  "labelsPerLanguage" : {
    "en" : "Internet",
    "fr" : "Internet"
  },
  "total" : 30,
  "currency" : "EUR",
  "country" : "FR",
  "category" : "other",
  "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
  "order" : 3,
  "disabled" : false,
  "requireReceipt" : false
}

Create a new allowance template

Request

POST /api/org/v1/organizations/{organizationId}/allowance-templates

Request body

Allowance template will be provided as a way to create an allowance, which is an expense with values filled from template at creation and not updatable after (like name, total, category, ...).

User will be able to update expense time, explanation, custom fields, ...

Values are copied on expense creation, updating a template after will not affect existing expenses.

field type description
labelsPerLanguage Map<String,String> The labels of the allowance template, per language, as displayed to front clients (web application, mobile applications). Created expense will use the label in the user language as label vaule.
total BigDecimal The total amount of the allowance.
currency String The currency of the total amount.
country String The country of the expense.
category String The category of the expense.
paymentMethodId String The identifier of the payment method which was used to pay the expense (for instance a credit card). Payment methods are declared on the groups of the organization.
order Integer Template order in the front selection list. Using a null value will put the template at the end of the list.
disabled Boolean Disable the template, making creation of new expense from it impossible.

Null value will be considered as false.

requireReceipt Boolean User must add a receipt with the allowance (default false). If no receipt is required, the category icon will be used instead.

Null value will be considered as false.

creationCondition ScopeCondition Allow to manage the availability of the template for the users, using advanced conditions

Response body

Allowance template will be provided as a way to create an allowance, which is an expense with values filled from template at creation and not updatable after (like name, total, category, ...).

User will be able to update expense time, explanation, custom fields, ...

Values are copied on expense creation, updating a template after will not affect existing expenses.

See AllowanceTemplate

Update allowances templates

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/allowance-templates/{templateId}" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "labelsPerLanguage" : {
                "en" : "Internet",
                "fr" : "Internet"
              },
              "total" : 28,
              "currency" : "EUR",
              "country" : "FR",
              "category" : "other",
              "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
              "disabled" : false
            }'
{
  "templateId" : "48bb29ff-61a6-43f9-9874-504692889555",
  "labelsPerLanguage" : {
    "en" : "Internet",
    "fr" : "Internet"
  },
  "total" : 28,
  "currency" : "EUR",
  "country" : "FR",
  "category" : "other",
  "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
  "order" : 3,
  "disabled" : false,
  "requireReceipt" : false
}

Update an existing allowance template. If no order is passed, it will keep the current order

Request

PUT /api/org/v1/organizations/{organizationId}/allowance-templates/{templateId}

Path variables

parameter type required description
templateId String true

Request body

Allowance template will be provided as a way to create an allowance, which is an expense with values filled from template at creation and not updatable after (like name, total, category, ...).

User will be able to update expense time, explanation, custom fields, ...

Values are copied on expense creation, updating a template after will not affect existing expenses.

field type description
labelsPerLanguage Map<String,String> The labels of the allowance template, per language, as displayed to front clients (web application, mobile applications). Created expense will use the label in the user language as label vaule.
total BigDecimal The total amount of the allowance.
currency String The currency of the total amount.
country String The country of the expense.
category String The category of the expense.
paymentMethodId String The identifier of the payment method which was used to pay the expense (for instance a credit card). Payment methods are declared on the groups of the organization.
order Integer Template order in the front selection list. Using a null value will put the template at the end of the list.
disabled Boolean Disable the template, making creation of new expense from it impossible.

Null value will be considered as false.

requireReceipt Boolean User must add a receipt with the allowance (default false). If no receipt is required, the category icon will be used instead.

Null value will be considered as false.

creationCondition ScopeCondition Allow to manage the availability of the template for the users, using advanced conditions

Response body

Allowance template will be provided as a way to create an allowance, which is an expense with values filled from template at creation and not updatable after (like name, total, category, ...).

User will be able to update expense time, explanation, custom fields, ...

Values are copied on expense creation, updating a template after will not affect existing expenses.

See AllowanceTemplate

Org. custom-fields

Custom fields are analytic fields freely defined by an organization, which may be filled in by a user when creating an expense.

List expense custom fields

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/custom-fields/expense" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "key" : "meal-type",
    "type" : "LIST",
    "listId" : "meal-type",
    "required" : true,
    "labelsPerLanguage" : {
      "en" : "Meal type",
      "fr" : "Type repas"
    },
    "order" : 0
  } ]
}

Fetch the list of expense custom fields

Request

GET /api/org/v1/organizations/{organizationId}/custom-fields/expense

Response body

field type description
data CustomField[]
data[].key String This is the unique code of the custom field.
data[].type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN

New types may be regularly added.

data[].minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
data[].maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.
data[].listId String Only for custom fields of type LIST, generated by the backend. ID required to manipulate the list of options associated with this custom field.
data[].required Boolean Whether the custom field is mandatory when creating an expense.
data[].labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
data[].editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
data[].visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
data[].order Integer Order of the custom field, for front clients.
data[].visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
data[].configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
data[].disableConfiguration Boolean Disable the button to configure the custom field within the app
data[].disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
data[].disableDeletion Boolean Disable the button to delete the custom field within the app
data[].validation CustomFieldValidation validation defines rules for custom field values.

Update all expense custom fields

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/custom-fields/expense" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '[ {
              "type" : "LIST",
              "required" : false,
              "labelsPerLanguage" : {
                "en" : "Meal type",
                "fr" : "Type repas"
              },
              "order" : 0,
              "key" : "meal-type"
            }, {
              "type" : "LONG",
              "required" : true,
              "labelsPerLanguage" : {
                "en" : "Number of nights",
                "fr" : "Nombre de nuits"
              },
              "order" : 1,
              "key" : "night-number"
            } ]'
{
  "data" : [ {
    "key" : "meal-type",
    "type" : "LIST",
    "listId" : "meal-type",
    "required" : false,
    "labelsPerLanguage" : {
      "en" : "Meal type",
      "fr" : "Type repas"
    },
    "order" : 0
  }, {
    "key" : "night-number",
    "type" : "LONG",
    "required" : true,
    "labelsPerLanguage" : {
      "en" : "Number of nights",
      "fr" : "Nombre de nuits"
    },
    "order" : 1
  } ]
}

Update the full list of expense custom fields.

Expense custom fields not included in the body (using the key attribute) will be disabled with an order putting them at the end of list. Disabled expense custom fields will be returned in the answer.

Request

PUT /api/org/v1/organizations/{organizationId}/custom-fields/expense

Request body

new list of expense custom fields to apply

field type description
type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN
  • FILES

New types may be regularly added.

required Boolean Whether the custom field is mandatory when creating an expense.
labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
order Integer Order of the custom field, for front clients.
visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
disableConfiguration Boolean Disable the button to configure the custom field within the app
disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
disableDeletion Boolean Disable the button to delete the custom field within the app
validation CustomFieldValidation
validation.minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
validation.maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.
key String This is the unique code of the custom field.
editableScopeCondition ScopeCondition Allow to manage the edibility using advanced conditions

Response body

The organization expense custom fields after update.

field type description
data CustomField[]
data[].key String This is the unique code of the custom field.
data[].type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN

New types may be regularly added.

data[].minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
data[].maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.
data[].listId String Only for custom fields of type LIST, generated by the backend. ID required to manipulate the list of options associated with this custom field.
data[].required Boolean Whether the custom field is mandatory when creating an expense.
data[].labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
data[].editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
data[].visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
data[].order Integer Order of the custom field, for front clients.
data[].visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
data[].configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
data[].disableConfiguration Boolean Disable the button to configure the custom field within the app
data[].disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
data[].disableDeletion Boolean Disable the button to delete the custom field within the app
data[].validation CustomFieldValidation validation defines rules for custom field values.

Update one expense custom field

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/custom-fields/expense/{customFieldKey}" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '[ {
              "type" : "LIST",
              "required" : false,
              "labelsPerLanguage" : {
                "en" : "Meal type",
                "fr" : "Type repas"
              },
              "order" : 0,
              "key" : "meal-type"
            }, {
              "type" : "LONG",
              "required" : true,
              "labelsPerLanguage" : {
                "en" : "Number of nights",
                "fr" : "Nombre de nuits"
              },
              "order" : 1,
              "key" : "night-number"
            } ]'
{
  "data" : [ {
    "key" : "meal-type",
    "type" : "LIST",
    "listId" : "meal-type",
    "required" : false,
    "labelsPerLanguage" : {
      "en" : "Meal type",
      "fr" : "Type repas"
    },
    "order" : 0
  }, {
    "key" : "night-number",
    "type" : "LONG",
    "required" : true,
    "labelsPerLanguage" : {
      "en" : "Number of nights",
      "fr" : "Nombre de nuits"
    },
    "order" : 1
  } ]
}
curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/custom-fields/expense/night-number" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "required" : true,
              "labelsPerLanguage" : {
                "en" : "Number of nights",
                "fr" : "Nombre de nuits"
              },
              "order" : 1,
              "visibleScopeCondition" : {
                "type" : "EBF_EQ",
                "field" : "CATEGORY",
                "value" : "hotel"
              }
            }'
{
  "key" : "night-number",
  "type" : "LONG",
  "required" : true,
  "labelsPerLanguage" : {
    "en" : "Number of nights",
    "fr" : "Nombre de nuits"
  },
  "order" : 1,
  "visibleScopeCondition" : {
    "type" : "EBF_EQ",
    "field" : "CATEGORY",
    "value" : "hotel"
  }
}

Update a single expense custom field.

Request

PUT /api/org/v1/organizations/{organizationId}/custom-fields/expense/{customFieldKey}

Path variables

parameter type required description
customFieldKey String true id of expense custom field to update

Request body

new expense custom field values

field type description
type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN
  • FILES

New types may be regularly added.

required Boolean Whether the custom field is mandatory when creating an expense.
labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
order Integer Order of the custom field, for front clients.
visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
disableConfiguration Boolean Disable the button to configure the custom field within the app
disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
disableDeletion Boolean Disable the button to delete the custom field within the app
validation CustomFieldValidation
validation.minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
validation.maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.

Response body

The updated expense custom fields

See CustomField

Delete one expense custom field

curl -X DELETE "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/custom-fields/expense/night-number" \
     -u API_USER_ID:SECRET_KEY \
null

Delete a single expense custom field.

Request

DELETE /api/org/v1/organizations/{organizationId}/custom-fields/expense/{customFieldKey}

Path variables

parameter type required description
customFieldKey String true id of the expense custom field to delete

Response body

204 No Content

field type description

Delete one vehicle custom field

Delete a single vehicle custom field.

Request

DELETE /api/org/v1/organizations/{organizationId}/custom-fields/vehicle/{customFieldKey}

Path variables

parameter type required description
customFieldKey String true id of the vehicle custom field to delete

Response body

204 No Content

field type description

List vehicle custom fields

Fetch the list of vehicle custom fields

Request

GET /api/org/v1/organizations/{organizationId}/custom-fields/vehicle

Response body

field type description
data CustomField[]
data[].key String This is the unique code of the custom field.
data[].type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN

New types may be regularly added.

data[].minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
data[].maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.
data[].listId String Only for custom fields of type LIST, generated by the backend. ID required to manipulate the list of options associated with this custom field.
data[].required Boolean Whether the custom field is mandatory when creating an expense.
data[].labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
data[].editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
data[].visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
data[].order Integer Order of the custom field, for front clients.
data[].visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
data[].configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
data[].disableConfiguration Boolean Disable the button to configure the custom field within the app
data[].disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
data[].disableDeletion Boolean Disable the button to delete the custom field within the app
data[].validation CustomFieldValidation validation defines rules for custom field values.

Update all vehicle custom fields

Update the full list of vehicle custom fields.

Vehicle custom fields not included in the body (using the key attribute) will be disabled with an order putting them at the end of list. Disabled vehicle custom fields will be returned in the answer.

Request

PUT /api/org/v1/organizations/{organizationId}/custom-fields/vehicle

Request body

new list of vehicle custom fields to apply

field type description
type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN
  • FILES

New types may be regularly added.

required Boolean Whether the custom field is mandatory when creating an expense.
labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
order Integer Order of the custom field, for front clients.
visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
disableConfiguration Boolean Disable the button to configure the custom field within the app
disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
disableDeletion Boolean Disable the button to delete the custom field within the app
validation CustomFieldValidation
validation.minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
validation.maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.
key String This is the unique code of the custom field.
editableScopeCondition ScopeCondition Allow to manage the edibility using advanced conditions

Response body

The organization custom fields after update.

field type description
data CustomField[]
data[].key String This is the unique code of the custom field.
data[].type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN

New types may be regularly added.

data[].minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
data[].maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.
data[].listId String Only for custom fields of type LIST, generated by the backend. ID required to manipulate the list of options associated with this custom field.
data[].required Boolean Whether the custom field is mandatory when creating an expense.
data[].labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
data[].editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
data[].visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
data[].order Integer Order of the custom field, for front clients.
data[].visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
data[].configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
data[].disableConfiguration Boolean Disable the button to configure the custom field within the app
data[].disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
data[].disableDeletion Boolean Disable the button to delete the custom field within the app
data[].validation CustomFieldValidation validation defines rules for custom field values.

Update one vehicle custom field

Update a single vehicle custom field.

Request

PUT /api/org/v1/organizations/{organizationId}/custom-fields/vehicle/{customFieldKey}

Path variables

parameter type required description
customFieldKey String true id of vehicle custom field to update

Request body

new vehicle custom field values

field type description
type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN
  • FILES

New types may be regularly added.

required Boolean Whether the custom field is mandatory when creating an expense.
labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
order Integer Order of the custom field, for front clients.
visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
disableConfiguration Boolean Disable the button to configure the custom field within the app
disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
disableDeletion Boolean Disable the button to delete the custom field within the app
validation CustomFieldValidation
validation.minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
validation.maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.

Response body

The updated vehicle custom fields

See CustomField

List custom field options

Fetch the list of options associated with a custom field of type 'LIST'.

Request

GET /api/org/v1/organizations/{organizationId}/custom-options/{listId}

Path variables

parameter type required description
listId String true

Response body

the list of all options for the specified list id.

field type description
data CustomOption[]
data[].id String This is the unique identifier of the custom option.
data[].labelsPerLanguage Map<String,String> Localized labels of the custom option. Organizations are encouraged to provide labels for each language they manage.
data[].extra String A field to hold extra information about the option, it can hold a complete JSON object.
data[].accountingCode String This is a code, used in accounting exports
data[].disabled Boolean The option may be disabled. It acts as a logical deletion, e.g. existing items still reference the option, but new ones cannot.
data[].scope String scope : the option must be seen by a user, a group or user owning custom field. For user, specify user Id. For group, specify group Id. For user custom field, specify user custom field value. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

data[].scopeCondition ScopeCondition scopeCondition : the option must be activate on calculated condition. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

Update custom field option

Create or update an option in a list of custom options.

Request

POST /api/org/v1/organizations/{organizationId}/custom-options/{listId}/options/{optionId}

Path variables

parameter type required description
listId String true
optionId String true

Request body

All data required to create or update the custom option.

field type description
id String This is the unique id of the custom option. Mandatory.
labelsPerLanguage Map<String,String> Localized labels of the custom option. Organizations are encouraged to provide labels for each language they manage. Optional (but highly recommended).
extra String A field to hold extra information about the option, it can hold a complete JSON object. Optional.
accountingCode String Code used in accounting exports. Optional.
disabled Boolean The option may be disabled. It acts as a logical deletion, e.g. existing items still reference the option, but new ones cannot. Optional.
scope String scope : the option must be seen by a user, a group or user owning custom field. For user, specify user Id. For group, specify group Id. For user custom field, specify user custom field value. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

scopeCondition ScopeCondition scopeCondition : the option must be activate on calculated condition. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

Response body

The created or updated option.

See CustomOption

Batch update custom field options

Create or update multiple options in a list of custom options.

Request

PATCH /api/org/v1/organizations/{organizationId}/custom-options/{listId}/options

Path variables

parameter type required description
listId String true

Request body

A list of data required to create or update each option.

field type description
id String This is the unique id of the custom option. Mandatory.
labelsPerLanguage Map<String,String> Localized labels of the custom option. Organizations are encouraged to provide labels for each language they manage. Optional (but highly recommended).
extra String A field to hold extra information about the option, it can hold a complete JSON object. Optional.
accountingCode String Code used in accounting exports. Optional.
disabled Boolean The option may be disabled. It acts as a logical deletion, e.g. existing items still reference the option, but new ones cannot. Optional.
scope String scope : the option must be seen by a user, a group or user owning custom field. For user, specify user Id. For group, specify group Id. For user custom field, specify user custom field value. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

scopeCondition ScopeCondition scopeCondition : the option must be activate on calculated condition. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

Response body

The list of created or updated options.

field type description
data CustomOption[]
data[].id String This is the unique identifier of the custom option.
data[].labelsPerLanguage Map<String,String> Localized labels of the custom option. Organizations are encouraged to provide labels for each language they manage.
data[].extra String A field to hold extra information about the option, it can hold a complete JSON object.
data[].accountingCode String This is a code, used in accounting exports
data[].disabled Boolean The option may be disabled. It acts as a logical deletion, e.g. existing items still reference the option, but new ones cannot.
data[].scope String scope : the option must be seen by a user, a group or user owning custom field. For user, specify user Id. For group, specify group Id. For user custom field, specify user custom field value. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

data[].scopeCondition ScopeCondition scopeCondition : the option must be activate on calculated condition. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

Delete custom field option

Delete an option from an existing list of custom options.

Be warned that deleting an option referenced by other entities might cause errors. You can safely update an option and disable it to avoid any error.

As deletion is an idempotent operation, deleting a non existing object will not result in an error.

Request

DELETE /api/org/v1/organizations/{organizationId}/custom-options/{listId}/options/{optionId}

Path variables

parameter type required description
listId String true
optionId String true

Delete all custom field options

Delete all options from an existing list of custom options.

Be warned that deleting an option referenced by other entities might cause errors. You can safely update an option and disable it to avoid any error.

As deletion is an idempotent operation, deleting a non existing object will not result in an error.

Request

DELETE /api/org/v1/organizations/{organizationId}/custom-options/{listId}/options

Path variables

parameter type required description
listId String true

Org. advanced customization

Set of methods to create, update or view expense warning rules of an organization>.

List expense warning rules

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/expense-warning-rules" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "e6de054b-f42f-4f7d-8c0a-e37928649b5e",
    "type" : "EXTERNAL",
    "labels" : {
      "en" : "Threshold excess",
      "fr" : "Dépassement de seuil"
    },
    "options" : [ {
      "code" : "m30",
      "labels" : {
        "en" : "Meal over 30€",
        "fr" : "Repas au dessus de 30€"
      }
    }, {
      "code" : "m60",
      "labels" : {
        "en" : "Meal over 60€",
        "fr" : "Repas au dessus de 60€"
      }
    }, {
      "code" : "t50",
      "labels" : {
        "en" : "Taxi over 50€",
        "fr" : "Taxi au dessus de 50€"
      }
    } ],
    "externalRuleId" : "my-warning-rule-id"
  } ]
}

Fetch the list of expense warning rule

Request

GET /api/org/v1/organizations/{organizationId}/expense-warning-rules

Response body

field type description
data WarningRule[]
data[].id String Unique identifier
data[].type WarningRuleType Rule type, for now only EXTERNAL type can be managed by api
data[].labels Map<String,String> Warning main label
data[].options WarningRuleOption[] Warning rule options.
data[].disabled Boolean Disabled rule.
data[].externalRuleId String The external rule ID (optional)

Create an expense warning rule

curl -X POST "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/expense-warning-rules" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "labels" : {
                "en" : "Threshold excess",
                "fr" : "Dépassement de seuil"
              },
              "options" : [ {
                "code" : "m30",
                "labels" : {
                  "en" : "Meal over 30€",
                  "fr" : "Repas au dessus de 30€"
                }
              }, {
                "code" : "m60",
                "labels" : {
                  "en" : "Meal over 60€",
                  "fr" : "Repas au dessus de 60€"
                }
              }, {
                "code" : "t50",
                "labels" : {
                  "en" : "Taxi over 50€",
                  "fr" : "Taxi au dessus de 50€"
                }
              } ],
              "externalRuleId" : "my-warning-rule-id"
            }'
{
  "id" : "e6de054b-f42f-4f7d-8c0a-e37928649b5e",
  "type" : "EXTERNAL",
  "labels" : {
    "en" : "Threshold excess",
    "fr" : "Dépassement de seuil"
  },
  "options" : [ {
    "code" : "m30",
    "labels" : {
      "en" : "Meal over 30€",
      "fr" : "Repas au dessus de 30€"
    }
  }, {
    "code" : "m60",
    "labels" : {
      "en" : "Meal over 60€",
      "fr" : "Repas au dessus de 60€"
    }
  }, {
    "code" : "t50",
    "labels" : {
      "en" : "Taxi over 50€",
      "fr" : "Taxi au dessus de 50€"
    }
  } ],
  "externalRuleId" : "my-warning-rule-id"
}

Create a single expense warning rule with EXTERNAL type.

Important : created rule will have to be affected to Expenses by API calls exclusively, Jenji will not do any computations to affect it automatically.

Request

POST /api/org/v1/organizations/{organizationId}/expense-warning-rules

Request body

new expense warning rule, you can provide an optional externalRuleId if needed

field type description
labels Map<String,String> Rule labels, en language is required
options WarningRuleOption[] Rule options
options[].code String Technical code for this option (letter, digits, dot, dash and underscore only)
options[].labels Map<String,String> Option labels, en language is required
type WarningRuleType Rule type, default value is EXTERNAL.
externalRuleId String The external rule ID (optional)

Response body

The created expense warning rule.

See WarningRule

Update an expense warning rule

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/expense-warning-rules/e6de054b-f42f-4f7d-8c0a-e37928649b5e" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "labels" : {
                "en" : "Threshold excess",
                "fr" : "Dépassement de seuil"
              },
              "options" : [ {
                "code" : "m30",
                "labels" : {
                  "en" : "Meal over 30€",
                  "fr" : "Repas au dessus de 30€"
                }
              }, {
                "code" : "t50",
                "labels" : {
                  "en" : "Taxi over 50€",
                  "fr" : "Taxi au dessus de 50€"
                }
              }, {
                "code" : "t150",
                "labels" : {
                  "en" : "Taxi over 150€",
                  "fr" : "Taxi au dessus de 150€"
                }
              } ],
              "externalRuleId" : "my-warning-rule-id"
            }'
{
  "id" : "e6de054b-f42f-4f7d-8c0a-e37928649b5e",
  "type" : "EXTERNAL",
  "labels" : {
    "en" : "Threshold excess",
    "fr" : "Dépassement de seuil"
  },
  "options" : [ {
    "code" : "m60",
    "labels" : {
      "en" : "Meal over 60€",
      "fr" : "Repas au dessus de 60€"
    }
  }, {
    "code" : "t150",
    "labels" : {
      "en" : "Taxi over 150€",
      "fr" : "Taxi au dessus de 150€"
    }
  } ],
  "externalRuleId" : "my-warning-rule-id"
}

Update a single expense warning rule.

Request

PUT /api/org/v1/organizations/{organizationId}/expense-warning-rules/{ruleId}

Path variables

parameter type required description
ruleId String true can be either Jenji ID or an external ID using the format 'ext-your-warning-rule-id'

Request body

expense warning rule new value

field type description
labels Map<String,String> Rule labels, en language is required
options WarningRuleOption[] Rule options
options[].code String Technical code for this option (letter, digits, dot, dash and underscore only)
options[].labels Map<String,String> Option labels, en language is required
externalRuleId String The external rule ID (optional)

Response body

The updated expense warning rule.

See WarningRule

Delete an expense warning rule

curl -X DELETE "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/expense-warning-rules/e6de054b-f42f-4f7d-8c0a-e37928649b5e" \
     -u API_USER_ID:SECRET_KEY \
null

Delete a single expense warning rule.

Request

DELETE /api/org/v1/organizations/{organizationId}/expense-warning-rules/{ruleId}

Path variables

parameter type required description
ruleId String true can be either Jenji ID or an external ID using the format 'ext-your-warning-rule-id'

Patch expense warning rules

curl -X PATCH "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/expense-warning-rules" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '[ {
              "id" : "e6de054b-f42f-4f7d-8c0a-e37928649b5e",
              "labels" : {
                "en" : "Threshold excess",
                "fr" : "Dépassement de seuil"
              },
              "options" : [ {
                "code" : "m30",
                "labels" : {
                  "en" : "Meal over 30€",
                  "fr" : "Repas au dessus de 30€"
                }
              }, {
                "code" : "m60",
                "labels" : {
                  "en" : "Meal over 60€",
                  "fr" : "Repas au dessus de 60€"
                }
              }, {
                "code" : "t50",
                "labels" : {
                  "en" : "Taxi over 50€",
                  "fr" : "Taxi au dessus de 50€"
                }
              } ]
            }, {
              "labels" : {
                "en" : "Weekend expense"
              }
            }, {
              "labels" : {
                "en" : "An external warning rule"
              },
              "externalRuleId" : "my-other-warning-rule-id"
            } ]'
{
  "data" : [ {
    "id" : "e6de054b-f42f-4f7d-8c0a-e37928649b5e",
    "type" : "EXTERNAL",
    "labels" : {
      "en" : "Threshold excess",
      "fr" : "Dépassement de seuil"
    },
    "options" : [ {
      "code" : "m30",
      "labels" : {
        "en" : "Meal over 30€",
        "fr" : "Repas au dessus de 30€"
      }
    }, {
      "code" : "m60",
      "labels" : {
        "en" : "Meal over 60€",
        "fr" : "Repas au dessus de 60€"
      }
    }, {
      "code" : "t50",
      "labels" : {
        "en" : "Taxi over 50€",
        "fr" : "Taxi au dessus de 50€"
      }
    } ],
    "externalRuleId" : "my-warning-rule-id"
  }, {
    "id" : "6095560c-c7dc-49ab-a04d-fd7f31ae2116",
    "type" : "EXTERNAL",
    "labels" : {
      "en" : "Weekend expense"
    }
  }, {
    "id" : "0821dae8-aa9d-4076-bfe0-fc7c0b78e961",
    "type" : "EXTERNAL",
    "labels" : {
      "en" : "An external warning rule"
    },
    "externalRuleId" : "my-other-warning-rule-id"
  } ]
}

Update or create multiple expense warning rules at once, with EXTERNAL type.

Matching is made on internal or external id, pass a null value in id to create a new rule.

Other existing rules not present in the body will not be updated

Important : created rules will have to be affected to Expenses by API calls exclusively, Jenji will not do any computations to affect them automatically.

Request

PATCH /api/org/v1/organizations/{organizationId}/expense-warning-rules

Request body

expense warning rules new value, you can provide an optional externalRuleId if needed

field type description
id String Existing rule id, if null will create a new rule. If present, it must match an existing rule.
labels Map<String,String> Rule labels, en language is required
options WarningRuleOption[] Rule options
options[].code String Technical code for this option (letter, digits, dot, dash and underscore only)
options[].labels Map<String,String> Option labels, en language is required
externalRuleId String The external rule ID (optional)

Response body

The updated expense warning rule.

field type description
data WarningRule[]
data[].id String Unique identifier
data[].type WarningRuleType Rule type, for now only EXTERNAL type can be managed by api
data[].labels Map<String,String> Warning main label
data[].options WarningRuleOption[] Warning rule options.
data[].disabled Boolean Disabled rule.
data[].externalRuleId String The external rule ID (optional)

Organization Users

Set of methods to create, update or view organization users. These methods may only be used by an organization, its bookkeeper, or the master bookkeeper of its bookkeeper.

List all users

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "62ea3fee-85c0-4810-8774-7206fdcc0ed2",
    "login" : "john.doe@sample.com",
    "email" : "john.doe@sample.com",
    "firstName" : "John",
    "lastName" : "Doe",
    "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
    "groupId" : "root",
    "internalId" : "ABC123",
    "customFields" : {
      "preferred-number" : 42,
      "role" : "director",
      "start" : 1522540800000
    },
    "updatedAt" : "2021-03-15T18:24:36Z",
    "createdAt" : "2018-03-15T18:24:36Z",
    "profiles" : [ {
      "profileId" : "director",
      "groupIds" : [ "root" ]
    } ],
    "mainAccount" : true,
    "delegations" : [ {
      "id" : "group-id",
      "groupId" : "group-id",
      "permission" : "WRITE"
    }, {
      "id" : "user-id",
      "userId" : "user-id",
      "permission" : "WRITE",
      "start" : "2021-12-08",
      "end" : "2021-12-15"
    } ]
  }, {
    "id" : "9378e35f-be89-4297-8034-d8791ad39119",
    "login" : "foo.bar@sample.com",
    "email" : "foo.bar@sample.com",
    "firstName" : "Foo",
    "lastName" : "Bar",
    "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
    "groupId" : "root",
    "internalId" : "AZE987",
    "customFields" : {
      "preferred-number" : 7,
      "role" : "driver",
      "start" : 1522540800000
    },
    "vehicles" : [ {
      "id" : "bb54bb44-1637-49ee-b019-dcb68f27760b",
      "type" : "CAR",
      "label" : "CLIO VI",
      "taxHorsepower" : 5,
      "engineCapacity" : 2946,
      "energy" : "PETROL",
      "checked" : false
    } ],
    "updatedAt" : "2021-05-15T18:24:36Z",
    "createdAt" : "2018-05-15T18:24:36Z",
    "blockedAt" : "2021-05-15T18:24:36Z",
    "mainAccount" : true
  } ]
}

List all the users of the organization.

Request

GET /api/org/v1/organizations/{organizationId}/users

Query parameters

parameter type required description
login String false
internalId String false

Response body

field type description
data User[]
data[].id String Unique identifier of the User in Jenji (UUID or email, depending on the acquisition channel).
data[].login String Login used by the user to authenticate to Jenji.
data[].email String Email address at which the user may be contacted, to receive technical notifications.
data[].firstName String First name of the user, like "Alex" in "Alex Pence".
data[].lastName String Last name of the user, like "Pence" in "Alex Pence".
data[].organizationId String Identifier of the organization to which the user belongs.
data[].groupId String Identifier of the organization group to which the user belongs.
data[].internalId String Identifier of the user in the information system of the organization.
data[].customFields Map<String,Object> Custom fields available specifically for this user, mapped by their key.
data[].vehicles Vehicle[] List of personal vehicles belonging to the user. These vehicles may be referenced in mileage expenses.
data[].preferredPaymentMethodId String Identifier of the preferred payment method of the user, to be selected by default in graphical interfaces.
data[].preferredCountry String Code of the preferred country of the user, to be selected by default in graphical interfaces.
data[].preferredCurrency String Code of the preferred currency of the user, to be selected by default in graphical interfaces.
data[].preferredDistanceUnit DistanceUnit Code of the preferred distance unit of the user. Allowed values are KM and MI, default is KM.
data[].preferredVehicleId String Identifier of the preferred vehicle of the user, to be selected by default in graphical interfaces.
data[].updatedAt OffsetDateTime Timestamp at which the user was last updated.
data[].createdAt OffsetDateTime Timestamp at which the user was created.
data[].blockedAt OffsetDateTime Timestamp at which the user was blocked. This field is null if the user is not blocked.
data[].profiles UserProfile[] List of profiles associated to the user, allowing him/her to work in the expense workflow.
data[].mainAccount Boolean Boolean indicating whether it is the user main/default account. Default is false, unless it is the only account.
data[].phone String The user phone number.
data[].delegations Delegation[] Delegations granted to the user, either on groups, or on other users.

Get user by ID

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/9378e35f-be89-4297-8034-d8791ad39119" \
     -u API_USER_ID:SECRET_KEY \
{
  "id" : "9378e35f-be89-4297-8034-d8791ad39119",
  "login" : "foo.bar@sample.com",
  "email" : "foo.bar@sample.com",
  "firstName" : "Foo",
  "lastName" : "Bar",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "groupId" : "root",
  "internalId" : "AZE987",
  "customFields" : {
    "preferred-number" : 7,
    "role" : "driver",
    "start" : 1522540800000
  },
  "vehicles" : [ {
    "id" : "bb54bb44-1637-49ee-b019-dcb68f27760b",
    "type" : "CAR",
    "label" : "CLIO VI",
    "taxHorsepower" : 5,
    "engineCapacity" : 2946,
    "energy" : "PETROL",
    "checked" : false
  } ],
  "updatedAt" : "2021-05-15T18:24:36Z",
  "createdAt" : "2018-05-15T18:24:36Z",
  "blockedAt" : "2021-05-15T18:24:36Z",
  "mainAccount" : true
}

Get a user by his ID.

Request

GET /api/org/v1/organizations/{organizationId}/users/{userId}

Response body

An organization user, or simply "user", belongs to a group of the organization. Users work at the different steps of the expense workflow, creating expenses, validating them or authorizing reimbursements.

See User

Create a new user

curl -X POST "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "login" : "dom.toretto@sample.com",
              "email" : "driver@sample.com",
              "firstName" : "Dominic",
              "lastName" : "Toretto",
              "groupId" : "root",
              "internalId" : "TFATF",
              "profiles" : [ {
                "profileId" : "director",
                "groupIds" : [ "root" ]
              } ],
              "customFields" : {
                "preferred-number" : 8,
                "role" : "driver",
                "start" : 1621123200000
              },
              "mainAccount" : true,
              "delegations" : [ {
                "userId" : "user-id",
                "permission" : "WRITE",
                "start" : "2021-12-08",
                "end" : "2021-12-15"
              }, {
                "groupId" : "group-id",
                "permission" : "WRITE"
              } ]
            }'
{
  "id" : "9378e35f-be89-4297-8034-d8791ad39119",
  "login" : "dom.toretto@sample.com",
  "email" : "driver@sample.com",
  "firstName" : "Dominic",
  "lastName" : "Toretto",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "groupId" : "root",
  "internalId" : "TFATF",
  "customFields" : {
    "preferred-number" : 8,
    "role" : "driver",
    "start" : 1621123200000
  },
  "updatedAt" : "2021-05-15T18:26:36Z",
  "createdAt" : "2021-05-15T18:26:36Z",
  "profiles" : [ {
    "profileId" : "director",
    "groupIds" : [ "root" ]
  } ],
  "mainAccount" : true,
  "delegations" : [ {
    "id" : "group-id",
    "groupId" : "group-id",
    "permission" : "WRITE"
  }, {
    "id" : "user-id",
    "userId" : "user-id",
    "permission" : "WRITE",
    "start" : "2021-12-08",
    "end" : "2021-12-15"
  } ]
}

Create a new organization user and adds it to a specific group of the organization.

Request

POST /api/org/v1/organizations/{organizationId}/users

Request body

The data required to create the user.

field type description
login String Mandatory. The login of the user, usually his/her email address. Must be unique.
email String Optional. Email to be used instead of login, if empty login will be used.
firstName String Optional. First name of the user, like "Alex" in "Alex Pence".
lastName String Optional. Last name of the user, like "Pence" in "Alex Pence".
language String Optional. Code of the primary language of the user (2 characters in lowercase, e.g. "fr" for French).
preferredPaymentMethodId String Optional. Identifier of the preferred payment method of the user.
preferredCountry String Optional. Code of the preferred country of the user (2 characters in uppercase, e.g. FR for France).
preferredCurrency String Optional. Code of the preferred currency of the user (3 characters in uppercase, e.g. EUR for Euro).
preferredVehicle String Optional. Code of the preferred vehicle of the user (vehicleId).
preferredDistanceUnit DistanceUnit Optional. Code of the preferred distance unit of the user (2 characters in uppercase, e.g. KM for Kilometer). Allowed values are KM and MI, default is KM.
groupId String Optional. The organization group in which the user must be created. If left empty, then the user will be added to the root group (same as group id root).
internalId String Optional. The internal code of the user, in the bookkeeper information system.
profiles UserProfile[] Optional. The profiles to associate to the user.
customFields Map<String,Object> Optional. Custom fields available specifically for this user, mapped by their key.
mainAccount Boolean Optional. Boolean indicating whether it is the main/default user account or not.
Default is false, unless it is the only account.
If the user already has a main/default account and mainAccount is true, the created user will become the new main account
phone String Optional. The user phone number.
delegations Delegation[] Optional. User or group delegations for the user.
delegations[].userId String Conditional. The identifier of the user on whom the current user is given a delegation. Either the userId or groupId must be filled.
delegations[].groupId String Conditional. The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated. Either the userId or groupId must be filled.
delegations[].permission DelegationPermission Mandatory. The permission type granted by the delegation (read-only, write etc).
delegations[].start LocalDate Conditional. Applies only to user delegations. When filled, end date must be filled as well. The date from which the delegation is valid.
delegations[].end LocalDate Conditional. Applies only to user delegations. When filled, start date must be filled as well. The date after which the delegation ends.

Response body

The newly-created user, with a unique ID.

See User

Update a user

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/{userId}" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "email" : "driver@sample.com",
              "firstName" : "Dominic",
              "lastName" : "Toretto",
              "internalId" : "TFATF",
              "profiles" : [ {
                "profileId" : "director",
                "groupIds" : [ "root" ]
              } ],
              "customFields" : {
                "preferred-number" : 9,
                "role" : "driver",
                "start" : 1621123200000
              }
            }'
{
  "id" : "9378e35f-be89-4297-8034-d8791ad39119",
  "login" : "dom.toretto@sample.com",
  "email" : "driver@sample.com",
  "firstName" : "Dominic",
  "lastName" : "Toretto",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "groupId" : "root",
  "internalId" : "TFATF",
  "customFields" : {
    "preferred-number" : 9,
    "role" : "driver",
    "start" : 1621123200000
  },
  "updatedAt" : "2022-11-24T17:04:27.164116Z",
  "createdAt" : "2021-05-15T18:26:36Z",
  "profiles" : [ {
    "profileId" : "director",
    "groupIds" : [ "root" ]
  } ],
  "mainAccount" : true,
  "delegations" : [ {
    "id" : "group-id",
    "groupId" : "group-id",
    "permission" : "WRITE"
  }, {
    "id" : "user-id",
    "userId" : "user-id",
    "permission" : "WRITE",
    "start" : "2021-12-08",
    "end" : "2021-12-15"
  } ]
}

Update an existing organization user. This is a PUT request, not a PATCH request: any field left empty will be cleared in the end, so make sure you fill in all fields which should have a value when calling this endpoint, paying extra attention to user profiles.

\u26a0\ufe0fBeware that delegations won't be affected, you need to use dedicated endpoints to update a user's delegations.

Request

PUT /api/org/v1/organizations/{organizationId}/users/{userId}

Request body

All data required to update the user.

field type description
email String Optional. Email to be used instead of login, if empty login will be used.
firstName String Optional. First name of the user, like "Alex" in "Alex Pence".
lastName String Optional. Last name of the user, like "Pence" in "Alex Pence".
language String Optional. Code of the primary language of the user (2 characters in lowercase, e.g. "fr" for French).
preferredPaymentMethodId String Optional. Identifier of the preferred payment method of the user.
preferredCountry String Optional. Code of the preferred country of the user (2 characters in uppercase, e.g. FR for France).
preferredCurrency String Optional. Code of the preferred currency of the user (3 characters in uppercase, e.g. EUR for Euro).
preferredVehicle String Optional. Code of the preferred vehicle of the user (vehicleId).
preferredDistanceUnit DistanceUnit Optional. Code of the preferred distance unit of the user (2 characters in uppercase, e.g. KM for Kilometer). Allowed values are KM and MI, default is KM.
groupId String Optional.The organization group in which the user must be created. If empty it will be kept as existent. Use root to put the user the root group
internalId String Optional. The internal code of the user, in the bookkeeper information system.
profiles UserProfile[] Optional. The profiles to associate to the user.
customFields Map<String,Object> Optional. Custom fields available specifically for this user, mapped by their key.
mainAccount Boolean Optional. Boolean indicating whether it is the user main/default account or not.
Default is false.
If the updated user already has a main/default account and mainAccount is true, the updated user will become the new main account
phone String Optional. The user phone number.

Response body

The updated user.

See User

Update a user login

Request

PATCH /api/org/v1/organizations/{organizationId}/users/{userId}/login

Request body

Updates an existing organization user login.

field type description
login String New login value.

Response body

An organization user, or simply "user", belongs to a group of the organization. Users work at the different steps of the expense workflow, creating expenses, validating them or authorizing reimbursements.

See User

List all user invitations

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/invitations" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "be46ff60-bcfa-438d-a23f-321d7f8183a1",
    "login" : "foo.bar@sample.com",
    "email" : "foo.bar@sample.com",
    "firstName" : "Foo",
    "lastName" : "Bar",
    "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
    "groupId" : "root",
    "internalId" : "AZE987",
    "customFields" : {
      "preferred-number" : 7,
      "role" : "driver",
      "start" : 1522540800000
    },
    "delegations" : [ {
      "id" : "group-id",
      "groupId" : "group-id",
      "permission" : "WRITE"
    }, {
      "id" : "user-id",
      "userId" : "user-id",
      "permission" : "WRITE",
      "start" : "2021-12-08",
      "end" : "2021-12-15"
    } ]
  } ]
}

List all the user invitations of the organization.

Request

GET /api/org/v1/organizations/{organizationId}/invitations

Response body

field type description
data UserInvitation[]
data[].id String Unique identifier of the User invitation in Jenji (UUID).
data[].login String Login used by the user to authenticate to Jenji.
data[].email String Email address at which the user may be contacted, to receive technical notifications.
data[].firstName String First name of the user, like "Alex" in "Alex Pence".
data[].lastName String Last name of the user, like "Pence" in "Alex Pence".
data[].organizationId String Identifier of the organization to which the user belongs.
data[].groupId String Identifier of the organization group to which the user belongs.
data[].internalId String Identifier of the user in the information system of the organization.
data[].customFields Map<String,Object> Custom fields available specifically for this user, mapped by their key. The definitions of custom fields are set on the root group.
data[].vehicles Vehicle[] List of personal vehicles belonging to the user. These vehicles may be referenced in mileage expenses.
data[].preferredPaymentMethodId String Identifier of the preferred payment method of the user, to be selected by default in graphical interfaces.
data[].preferredCountry String Code of the preferred country of the user, to be selected by default in graphical interfaces.
data[].preferredCurrency String Code of the preferred currency of the user, to be selected by default in graphical interfaces.
data[].state String State of the user invitation. The state can be "WAITING", "ACCEPTED" or "DELETED".
data[].inviteSentAt OffsetDateTime Timestamp at which the user invitation was sent.
data[].createdAt OffsetDateTime Timestamp at which the user invitation was created.
data[].deletedAt OffsetDateTime Timestamp at which the user invitation was deleted. This field is null if the user invitation is not deleted.
data[].profiles UserProfile[] List of profiles associated with the user, allowing him/her to work in the expense workflow.
data[].phone String The user phone number.
data[].delegations Delegation[] Delegations to be granted to the user, either on groups, or on other users.

Create a new user invitation

curl -X POST "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/invitations" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "login" : "foo.bar@sample.com",
              "email" : "foo.bar@sample.com",
              "firstName" : "Foo",
              "lastName" : "Bar",
              "groupId" : "root",
              "internalId" : "AZE987",
              "customFields" : {
                "preferred-number" : 7,
                "role" : "driver",
                "start" : 1522540800000
              },
              "delegations" : [ {
                "groupId" : "group-id",
                "permission" : "WRITE"
              }, {
                "userId" : "user-id",
                "permission" : "WRITE",
                "start" : "2021-12-08",
                "end" : "2021-12-15"
              } ]
            }'
{
  "id" : "b1c19099-7758-4750-8d5a-b9e22a2fe7a4",
  "login" : "foo.bar@sample.com",
  "email" : "foo.bar@sample.com",
  "firstName" : "Foo",
  "lastName" : "Bar",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "groupId" : "root",
  "internalId" : "AZE987",
  "customFields" : {
    "preferred-number" : 7,
    "role" : "driver",
    "start" : 1522540800000
  },
  "delegations" : [ {
    "id" : "group-id",
    "groupId" : "group-id",
    "permission" : "WRITE"
  }, {
    "id" : "user-id",
    "userId" : "user-id",
    "permission" : "WRITE",
    "start" : "2021-12-08",
    "end" : "2021-12-15"
  } ]
}

Create a new user invitation for an organization.

If a user with the same login already exist in the organization, an error will be thrown.

Request

POST /api/org/v1/organizations/{organizationId}/invitations

Request body

The data required to create the user invitation.

field type description
login String Mandatory. The login of the user, usually his/her email address. Must be unique.
email String Optional. Email to be used instead of login, if empty login will be used.
firstName String Optional. First name of the user, like "Alex" in "Alex Pence".
lastName String Optional. Last name of the user, like "Pence" in "Alex Pence".
language String Optional. Code of the primary language of the user (2 characters in lowercase, e.g. "fr" for French).
preferredPaymentMethodId String Optional. Identifier of the preferred payment method of the user.
preferredCountry String Optional. Code of the preferred country of the user (2 characters in uppercase, e.g. FR for France).
preferredCurrency String Optional. Code of the preferred currency of the user (3 characters in uppercase, e.g. EUR for Euro).
groupId String Optional. The organization group in which the user must be created. If left empty, then the user will be added to the root group.
internalId String Optional. The internal code of the user, in the bookkeeper information system.
profiles UserProfile[] Optional. The profiles to associate to the user.
skipMail Boolean Optional. Set to true if you do not want the email to be sent.
customFields Map<String,Object> Optional. Custom fields available specifically for this user, mapped by their key.
phone String Optional. The user phone number.
delegations Delegation[] Optional. User or group delegations for the user.
delegations[].userId String Conditional. The identifier of the user on whom the current user is given a delegation. Either the userId or groupId must be filled.
delegations[].groupId String Conditional. The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated. Either the userId or groupId must be filled.
delegations[].permission DelegationPermission Mandatory. The permission type granted by the delegation (read-only, write etc).
delegations[].start LocalDate Conditional. Applies only to user delegations. When filled, end date must be filled as well. The date from which the delegation is valid.
delegations[].end LocalDate Conditional. Applies only to user delegations. When filled, start date must be filled as well. The date after which the delegation ends.

Response body

The newly-created user invitation, with a unique ID.

See UserInvitation

Block a user

Block a user of the organization. This user will not be able to access Jenji services anymore.

Request

POST /api/org/v1/organizations/{organizationId}/users/{userId}/block

Response body

The blocked user.

See User

Unblock a user

Unblock a user of the organization. This user may access Jenji services again.

Request

POST /api/org/v1/organizations/{organizationId}/users/{userId}/unblock

Response body

The unblocked user.

See User

List all user vehicles

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/my-user-id/vehicles" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "12c0b25a-f53e-48e8-a91e-a3bbbc9026fd",
    "type" : "CAR",
    "label" : "CLIO III",
    "taxHorsepower" : 7,
    "engineCapacity" : 1149,
    "energy" : "PETROL",
    "checked" : false
  } ]
}

List all vehicles for an organization user.

Request

GET /api/org/v1/organizations/{organizationId}/users/{userId}/vehicles

Response body

field type description
data Vehicle[]
data[].id String Unique identifier of the vehicle in Jenji (UUID).
data[].type VehicleType Type of the vehicle, like a car or a motorcycle. Estimation policies for mileage expenses differ depending on the type.
data[].label String The label of the vehicle, to help the user select the right vehicle when creating an expense.
data[].taxHorsepower int Tax horsepower of the vehicle, used to estimate the expense.
data[].engineCapacity Integer The engine capacity in cubic centimeters (cc).
data[].energy VehicleEnergy The energy used in the vehicle (Petrol, Diesel, Electric, LPG).
data[].fixedMileageRate BigDecimal Fixed mileage reimbursement rate, set by the organization, which overrides official tariffs.
data[].fixedMileageRateDistanceUnit DistanceUnit Fixed mileage reimbursement rate distance unit (km or miles)
data[].mileageCalculatorId String The specific mileage calculator to use when computing mileage expenses for this vehicle. When missing, mileage expenses are computed with the default rules applicable for the organization.
data[].disabledAt OffsetDateTime Timestamp at which the vehicle has been disabled. It may not be used in expenses anymore, but remains in the system for history purposes.
data[].checked boolean Whether the registration document has been verified.
data[].customFields Map<String,Object> Custom fields available specifically for this vehicle, mapped by their key.

VehicleType

value description
CAR
MOTORCYCLE
MOPED
BIKE

VehicleEnergy

Energy for a vehicle. Can be used by some mileage calculators to estimate a mileage expense.

value description
ELECTRIC Full electric. Hybrid cars are treated as either petrol or diesel cars for advisory fuel rates.
PETROL
DIESEL
LPG Liquefied Petroleum Gas.

Create a user vehicle

curl -X POST "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/my-user-id/vehicles" \
     -u API_USER_ID:SECRET_KEY \
{
  "id" : "12c0b25a-f53e-48e8-a91e-a3bbbc9026fd",
  "type" : "CAR",
  "label" : "CLIO III",
  "taxHorsepower" : 7,
  "engineCapacity" : 1149,
  "energy" : "PETROL",
  "checked" : false
}

Add a vehicle for an user.

Request

POST /api/org/v1/organizations/{organizationId}/users/{userId}/vehicles

Request body

A personal vehicle for an organization user. Vehicles are registered to create and estimate mileage expenses, when an organization user travels with his/her personal vehicle, for business.

field type description
label String The label of the vehicle, to help the user select the right vehicle when creating an expense.
engineCapacity Integer Optional. Engine capacity, in cubic centimeters (cc).
energy VehicleEnergy Optional. The energy for the vehicle, one of {PETROL, ELECTRIC, DIESEL, LPG}. Can be used to compute mileage allowances for this vehicle.
fixedMileageRate BigDecimal Fixed mileage reimbursement rate, set by the organization, which overrides official tariffs.
fixedMileageRateDistanceUnit DistanceUnit Fixed mileage reimbursement rate distance unit (km or miles).

Default to KM.

mileageCalculatorId String Optional. Identifier of a specific mileage calculator, to be used for this vehicle. If missing, mileage computation use the default rules applicable to the organization.
disabled Boolean Disable the vehicle
customFields Map<String,Object> Custom fields available specifically for this user, mapped by their key.
type VehicleType Type of the vehicle, like a car or a motorcycle. Estimation policies for mileage expenses differ depending on the type.
taxHorsepower Integer Tax horsepower of the vehicle, used to estimate the expense.

Response body

A personal vehicle for an organization user. Vehicles are registered to create and estimate mileage expenses, when an organization user travels with his/her personal vehicle, for business.

See Vehicle

VehicleEnergy

Energy for a vehicle. Can be used by some mileage calculators to estimate a mileage expense.

value description
ELECTRIC Full electric. Hybrid cars are treated as either petrol or diesel cars for advisory fuel rates.
PETROL
DIESEL
LPG Liquefied Petroleum Gas.

VehicleType

value description
CAR
MOTORCYCLE
MOPED
BIKE

Update a user vehicle

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/my-user-id/vehicles/{vehicleId}" \
     -u API_USER_ID:SECRET_KEY \
{
  "id" : "12c0b25a-f53e-48e8-a91e-a3bbbc9026fd",
  "type" : "CAR",
  "label" : "CLIO III",
  "taxHorsepower" : 7,
  "engineCapacity" : 1149,
  "energy" : "PETROL",
  "disabledAt" : "2022-11-24T17:04:27.225612Z",
  "checked" : false
}

Update a vehicle for an user.

Request

PUT /api/org/v1/organizations/{organizationId}/users/{userId}/vehicles/{vehicleId}

Path variables

parameter type required description
vehicleId String true

Request body

A personal vehicle for an organization user. Vehicles are registered to create and estimate mileage expenses, when an organization user travels with his/her personal vehicle, for business.

field type description
label String The label of the vehicle, to help the user select the right vehicle when creating an expense.
engineCapacity Integer Optional. Engine capacity, in cubic centimeters (cc).
energy VehicleEnergy Optional. The energy for the vehicle, one of {PETROL, ELECTRIC, DIESEL, LPG}. Can be used to compute mileage allowances for this vehicle.
fixedMileageRate BigDecimal Fixed mileage reimbursement rate, set by the organization, which overrides official tariffs.
fixedMileageRateDistanceUnit DistanceUnit Fixed mileage reimbursement rate distance unit (km or miles).

Default to KM.

mileageCalculatorId String Optional. Identifier of a specific mileage calculator, to be used for this vehicle. If missing, mileage computation use the default rules applicable to the organization.
disabled Boolean Disable the vehicle
customFields Map<String,Object> Custom fields available specifically for this user, mapped by their key.

Response body

A personal vehicle for an organization user. Vehicles are registered to create and estimate mileage expenses, when an organization user travels with his/her personal vehicle, for business.

See Vehicle

VehicleEnergy

Energy for a vehicle. Can be used by some mileage calculators to estimate a mileage expense.

value description
ELECTRIC Full electric. Hybrid cars are treated as either petrol or diesel cars for advisory fuel rates.
PETROL
DIESEL
LPG Liquefied Petroleum Gas.

List all delegations

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/c21e0ca0-fa0e-49c8-bd3b-31d5ce2bcecc/delegations" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "group-id",
    "groupId" : "group-id",
    "permission" : "WRITE"
  }, {
    "id" : "user-id",
    "userId" : "user-id",
    "permission" : "WRITE",
    "start" : "2021-12-08",
    "end" : "2021-12-15"
  } ]
}

List all delegations for an organization user.

Request

GET /api/org/v1/organizations/{organizationId}/users/{userId}/delegations

Response body

field type description
data Delegation[]
data[].id String The delegation identifier, autogenerated with user id or group id if not present
data[].userId String The identifier of the user on whom the current user is given a delegation.
data[].groupId String The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated.
data[].permission DelegationPermission The permission type granted by the delegation (read-only, write etc).
data[].start LocalDate The date from which the delegation is valid. Only applies to user delegations.
data[].end LocalDate The date after which the delegation ends. Only applies to user delegations.

List all user delegations

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/c21e0ca0-fa0e-49c8-bd3b-31d5ce2bcecc/delegations/users" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "user-id",
    "userId" : "user-id",
    "permission" : "WRITE",
    "start" : "2021-12-08",
    "end" : "2021-12-15"
  } ]
}

List all user delegations for an organization user.

Request

GET /api/org/v1/organizations/{organizationId}/users/{userId}/delegations/users

Response body

field type description
data Delegation[]
data[].id String The delegation identifier, autogenerated with user id or group id if not present
data[].userId String The identifier of the user on whom the current user is given a delegation.
data[].groupId String The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated.
data[].permission DelegationPermission The permission type granted by the delegation (read-only, write etc).
data[].start LocalDate The date from which the delegation is valid. Only applies to user delegations.
data[].end LocalDate The date after which the delegation ends. Only applies to user delegations.

List all group delegations

curl -X GET "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/c21e0ca0-fa0e-49c8-bd3b-31d5ce2bcecc/delegations/groups" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "id" : "group-id",
    "groupId" : "group-id",
    "permission" : "WRITE"
  } ]
}

List all group delegations for an organization user.

Request

GET /api/org/v1/organizations/{organizationId}/users/{userId}/delegations/groups

Response body

field type description
data Delegation[]
data[].id String The delegation identifier, autogenerated with user id or group id if not present
data[].userId String The identifier of the user on whom the current user is given a delegation.
data[].groupId String The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated.
data[].permission DelegationPermission The permission type granted by the delegation (read-only, write etc).
data[].start LocalDate The date from which the delegation is valid. Only applies to user delegations.
data[].end LocalDate The date after which the delegation ends. Only applies to user delegations.

Update delegations

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/c21e0ca0-fa0e-49c8-bd3b-31d5ce2bcecc/delegations" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "delegations" : [ {
                "groupId" : "group-id",
                "permission" : "WRITE"
              }, {
                "userId" : "user-id",
                "permission" : "WRITE",
                "start" : "2021-12-08",
                "end" : "2021-12-15"
              } ]
            }'
{
  "data" : [ {
    "id" : "group-id",
    "groupId" : "group-id",
    "permission" : "WRITE"
  }, {
    "id" : "user-id",
    "userId" : "user-id",
    "permission" : "WRITE",
    "start" : "2021-12-08",
    "end" : "2021-12-15"
  } ]
}

Update delegations for a user. Delegations will be completely replaced by the ones passed as parameter, so make sure to provide all delegations for the user (both group and user delegations).

Request

PUT /api/org/v1/organizations/{organizationId}/users/{userId}/delegations

Request body

List of delegations granted to the user. Must contain all delegations for the user.

field type description
delegations Delegation[] List of all delegations to update for the user. When empty, will remove all delegations for the user.
delegations[].userId String Conditional. The identifier of the user on whom the current user is given a delegation. Either the userId or groupId must be filled.
delegations[].groupId String Conditional. The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated. Either the userId or groupId must be filled.
delegations[].permission DelegationPermission Mandatory. The permission type granted by the delegation (read-only, write etc).
delegations[].start LocalDate Conditional. Applies only to user delegations. When filled, end date must be filled as well. The date from which the delegation is valid.
delegations[].end LocalDate Conditional. Applies only to user delegations. When filled, start date must be filled as well. The date after which the delegation ends.

Response body

field type description
data Delegation[]
data[].id String The delegation identifier, autogenerated with user id or group id if not present
data[].userId String The identifier of the user on whom the current user is given a delegation.
data[].groupId String The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated.
data[].permission DelegationPermission The permission type granted by the delegation (read-only, write etc).
data[].start LocalDate The date from which the delegation is valid. Only applies to user delegations.
data[].end LocalDate The date after which the delegation ends. Only applies to user delegations.

Update user delegations

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/c21e0ca0-fa0e-49c8-bd3b-31d5ce2bcecc/delegations/users" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "delegations" : [ {
                "userId" : "user-id",
                "permission" : "WRITE",
                "start" : "2021-12-08",
                "end" : "2021-12-15"
              } ]
            }'
{
  "data" : [ {
    "id" : "user-id",
    "userId" : "user-id",
    "permission" : "WRITE",
    "start" : "2021-12-08",
    "end" : "2021-12-15"
  } ]
}

Update user delegations for a user. Delegations will be completely replaced by the ones passed as parameter, so make sure to provide all user delegations for the user.

Request

PUT /api/org/v1/organizations/{organizationId}/users/{userId}/delegations/users

Request body

List of delegations granted to the user. Must contain all delegations for the user.

field type description
delegations Delegation[] List of all delegations to update for the user. When empty, will remove all delegations for the user.
delegations[].userId String Conditional. The identifier of the user on whom the current user is given a delegation. Either the userId or groupId must be filled.
delegations[].groupId String Conditional. The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated. Either the userId or groupId must be filled.
delegations[].permission DelegationPermission Mandatory. The permission type granted by the delegation (read-only, write etc).
delegations[].start LocalDate Conditional. Applies only to user delegations. When filled, end date must be filled as well. The date from which the delegation is valid.
delegations[].end LocalDate Conditional. Applies only to user delegations. When filled, start date must be filled as well. The date after which the delegation ends.

Response body

field type description
data Delegation[]
data[].id String The delegation identifier, autogenerated with user id or group id if not present
data[].userId String The identifier of the user on whom the current user is given a delegation.
data[].groupId String The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated.
data[].permission DelegationPermission The permission type granted by the delegation (read-only, write etc).
data[].start LocalDate The date from which the delegation is valid. Only applies to user delegations.
data[].end LocalDate The date after which the delegation ends. Only applies to user delegations.

Update group delegations

curl -X PUT "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/users/c21e0ca0-fa0e-49c8-bd3b-31d5ce2bcecc/delegations/groups" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "delegations" : [ {
                "groupId" : "group-id",
                "permission" : "WRITE"
              } ]
            }'
{
  "data" : [ {
    "id" : "group-id",
    "groupId" : "group-id",
    "permission" : "WRITE"
  } ]
}

Update group delegations for a user. Delegations will be completely replaced by the ones passed as parameter, so make sure to provide all group delegations for the user.

Request

PUT /api/org/v1/organizations/{organizationId}/users/{userId}/delegations/groups

Request body

List of delegations granted to the user. Must contain all delegations for the user.

field type description
delegations Delegation[] List of all delegations to update for the user. When empty, will remove all delegations for the user.
delegations[].userId String Conditional. The identifier of the user on whom the current user is given a delegation. Either the userId or groupId must be filled.
delegations[].groupId String Conditional. The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated. Either the userId or groupId must be filled.
delegations[].permission DelegationPermission Mandatory. The permission type granted by the delegation (read-only, write etc).
delegations[].start LocalDate Conditional. Applies only to user delegations. When filled, end date must be filled as well. The date from which the delegation is valid.
delegations[].end LocalDate Conditional. Applies only to user delegations. When filled, start date must be filled as well. The date after which the delegation ends.

Response body

field type description
data Delegation[]
data[].id String The delegation identifier, autogenerated with user id or group id if not present
data[].userId String The identifier of the user on whom the current user is given a delegation.
data[].groupId String The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated.
data[].permission DelegationPermission The permission type granted by the delegation (read-only, write etc).
data[].start LocalDate The date from which the delegation is valid. Only applies to user delegations.
data[].end LocalDate The date after which the delegation ends. Only applies to user delegations.

Expenses

Set of methods to create, update or query expenses. These methods may only be called by the organization for its own expenses, or by its bookkeeper.

Search expenses of an organization

curl -X POST "https://api-test.jenji.io/api/org/v1/organizations/b48f8a89-e467-4b93-9aa4-196bd64c796a/expenses/search" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "searchMode" : "TIME",
              "start" : "2020-12-20",
              "end" : "2020-12-24",
              "states" : [ ],
              "includeDeleted" : false
            }'
{
  "data" : [ {
    "id" : "251652d1-9de9-4b7e-b890-5e04d4761b33",
    "userId" : "test@domain.com",
    "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
    "time" : "2020-12-20",
    "total" : 7.11,
    "currency" : "EUR",
    "country" : "FR",
    "billable" : false,
    "state" : "WAITING_FOR_VALIDATION",
    "label" : "Burrito",
    "customFields" : {
      "" : ""
    },
    "createdAt" : "2021-02-19T09:51:20.000000987Z",
    "createdWith" : "api/v1",
    "category" : "lunch",
    "receiptKey" : "test@domain.com/ee7cff0b-730c-46c3-86a2-9c0cde13d12a.jpg",
    "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
    "totalWithoutTax" : 5.93,
    "taxes" : [ {
      "baseAmount" : 5.93,
      "rate" : 20,
      "amount" : 1.19
    } ],
    "type" : "STANDARD"
  }, {
    "id" : "11cc8b82-1853-4640-ba9f-8607d83cd03a",
    "userId" : "test@domain.com",
    "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
    "time" : "2020-12-24",
    "total" : 340.58,
    "currency" : "EUR",
    "country" : "FR",
    "billable" : false,
    "state" : "WAITING_FOR_VALIDATION",
    "label" : "Rouen Paris",
    "createdAt" : "2021-02-24T15:42:54.000000987Z",
    "createdWith" : "android/sdk-1.6.0",
    "distance" : 324,
    "vehicleId" : "27092d19-ee07-45cd-937a-a40bac105408",
    "type" : "MILEAGE"
  } ]
}

Search for expenses for an organization, according to specified criteria. Returned expenses may be of different types, like standard or mileage expenses.

Request

POST /api/org/v1/organizations/{organizationId}/expenses/search

Request body

The criteria to search for.

field type description
searchMode SEARCH_MODE Mandatory if you specify a period. Determines which date to search on (creation or imputation). Default value is TIME (imputation).
start LocalDate Mandatory if you specify a period. Inclusive start of the search interval as a local date (YYYY-MM-DD).
end LocalDate Mandatory if you specify a period. Inclusive end of the search interval as a local date (YYYY-MM-DD).
states String[] Optional. List of states to match when searching expenses. Possible states include: 'ACCEPTED', 'WAITING_FOR_VALIDATION', 'EXPORTED', 'ACCOUNTED', 'PAID'.
includeDeleted Boolean Optional. Whether to include deleted expenses in the search. False when not specified.

Response body

List of expenses matching the search criteria.

field type description
data Expense[]
data[].id String Unique identifier of the expense in Jenji (a UUID).
data[].userId String Unique identifier of the organization user for which the expense applies (either an email or a UUID, depending on the acquisition channel).
data[].organizationId String Unique identifier of the organization to which the expense user belongs. This identifier is determined by the routing rules declared for the organization, and is set right after the expense creation.
data[].time LocalDate Day on which the expense occurred (imputation).
data[].explanation String Explanation for the expense, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
data[].tags String[] Simple labels, freely settable by the user who creates the expense. Tags may be used to search and find expenses easily in the various front clients (web application, mobile applications).
data[].total BigDecimal The total amount of the expense, including taxes.
data[].currency String The currency of the total amount. This currency should match the one specified in the receipt, when there is a receipt available.
data[].country String The country in which the expense occurred.
data[].billable Boolean Whether the expense may be billed to another party.
data[].reimbursable Boolean Whether the expense may be reimbursed to the user who has created it.
data[].attendees String[] The expense may be related to an event to which many users of the organization have attended. In such cases, the list of attendees contain the identifiers or these users.
data[].state String The state the expense is in, when the query is performed. The state may vary across organizations, depending on whether they have defined a custom workflow for expense management.
data[].label String The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...).
data[].customFields Map<String,Object> Custom fields are defined by organizations, to help classify an expense for analytic purposes. This fields maps values for all required custom fields.
data[].reimbursement Reimbursement Contains all the details of the reimbursement of the expense to the user. This field is only set after the expense has been validated.
data[].createdAt OffsetDateTime Timestamp at which the expense was created.
data[].createdWith String Medium through which the expense was created (mobile phone, web service...).
data[].updatedAt OffsetDateTime Timestamp at which the expense was last updated.
data[].validatedBy String Identifier of the user who has validated the expense (standard workflow).
data[].validatedAt OffsetDateTime Timestamp at which the expense was validated (standard workflow).
data[].accountedBy String Identifier of the user who has exported the expense for accounting (standard workflow).
data[].accountedAt OffsetDateTime Timestamp at which the expense was accounted for (standard workflow).
data[].paidBy String Identifier of the user who has authorized the reimbursement of the expense (standard workflow).
data[].paidAt OffsetDateTime Timestamp at which the expense was reimbursed to the user (standard workflow).
data[].checkedBy String Identifier of the user who has checked the expense (standard workflow).
data[].checkedAt OffsetDateTime Timestamp at which the expense was checked (standard workflow).
data[].deletedBy String Identifier of the user who has deleted the expense (standard workflow).
data[].deletedAt OffsetDateTime Timestamp at which the expense was deleted (standard workflow).
data[].warnings ExpenseWarning[] List of the expense warnings (duplicate, invalid receipt...).
data[].type ExpenseType

SEARCH_MODE

Determines which date the search interval applies to.

value description
TIME Apply the search interval to the imputation date of expenses.
CREATION Apply the search interval to the creation date of expenses.

Search expenses of your organization

curl -X POST "https://api-test.jenji.io/api/org/v1/expenses/search" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "searchMode" : "TIME",
              "start" : "2020-12-20",
              "end" : "2020-12-24",
              "states" : [ ],
              "includeDeleted" : false
            }'
{
  "data" : [ ]
}

Search for expenses of your own organization (as a root admin), according to specified criteria. Returned expenses may be of different types, like standard or mileage expenses.

Request

POST /api/org/v1/expenses/search

Request body

The criteria to search for.

field type description
searchMode SEARCH_MODE Mandatory if you specify a period. Determines which date to search on (creation or imputation). Default value is TIME (imputation).
start LocalDate Mandatory if you specify a period. Inclusive start of the search interval as a local date (YYYY-MM-DD).
end LocalDate Mandatory if you specify a period. Inclusive end of the search interval as a local date (YYYY-MM-DD).
states String[] Optional. List of states to match when searching expenses. Possible states include: 'ACCEPTED', 'WAITING_FOR_VALIDATION', 'EXPORTED', 'ACCOUNTED', 'PAID'.
includeDeleted Boolean Optional. Whether to include deleted expenses in the search. False when not specified.

Response body

List of expenses matching the search criteria.

field type description
data Expense[]
data[].id String Unique identifier of the expense in Jenji (a UUID).
data[].userId String Unique identifier of the organization user for which the expense applies (either an email or a UUID, depending on the acquisition channel).
data[].organizationId String Unique identifier of the organization to which the expense user belongs. This identifier is determined by the routing rules declared for the organization, and is set right after the expense creation.
data[].time LocalDate Day on which the expense occurred (imputation).
data[].explanation String Explanation for the expense, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
data[].tags String[] Simple labels, freely settable by the user who creates the expense. Tags may be used to search and find expenses easily in the various front clients (web application, mobile applications).
data[].total BigDecimal The total amount of the expense, including taxes.
data[].currency String The currency of the total amount. This currency should match the one specified in the receipt, when there is a receipt available.
data[].country String The country in which the expense occurred.
data[].billable Boolean Whether the expense may be billed to another party.
data[].reimbursable Boolean Whether the expense may be reimbursed to the user who has created it.
data[].attendees String[] The expense may be related to an event to which many users of the organization have attended. In such cases, the list of attendees contain the identifiers or these users.
data[].state String The state the expense is in, when the query is performed. The state may vary across organizations, depending on whether they have defined a custom workflow for expense management.
data[].label String The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...).
data[].customFields Map<String,Object> Custom fields are defined by organizations, to help classify an expense for analytic purposes. This fields maps values for all required custom fields.
data[].reimbursement Reimbursement Contains all the details of the reimbursement of the expense to the user. This field is only set after the expense has been validated.
data[].createdAt OffsetDateTime Timestamp at which the expense was created.
data[].createdWith String Medium through which the expense was created (mobile phone, web service...).
data[].updatedAt OffsetDateTime Timestamp at which the expense was last updated.
data[].validatedBy String Identifier of the user who has validated the expense (standard workflow).
data[].validatedAt OffsetDateTime Timestamp at which the expense was validated (standard workflow).
data[].accountedBy String Identifier of the user who has exported the expense for accounting (standard workflow).
data[].accountedAt OffsetDateTime Timestamp at which the expense was accounted for (standard workflow).
data[].paidBy String Identifier of the user who has authorized the reimbursement of the expense (standard workflow).
data[].paidAt OffsetDateTime Timestamp at which the expense was reimbursed to the user (standard workflow).
data[].checkedBy String Identifier of the user who has checked the expense (standard workflow).
data[].checkedAt OffsetDateTime Timestamp at which the expense was checked (standard workflow).
data[].deletedBy String Identifier of the user who has deleted the expense (standard workflow).
data[].deletedAt OffsetDateTime Timestamp at which the expense was deleted (standard workflow).
data[].warnings ExpenseWarning[] List of the expense warnings (duplicate, invalid receipt...).
data[].type ExpenseType

SEARCH_MODE

Determines which date the search interval applies to.

value description
TIME Apply the search interval to the imputation date of expenses.
CREATION Apply the search interval to the creation date of expenses.

View an expense

curl -X GET "https://api-test.jenji.io/api/org/v1/expenses/251652d1-9de9-4b7e-b890-5e04d4761b33" \
     -u API_USER_ID:SECRET_KEY \
{
  "id" : "251652d1-9de9-4b7e-b890-5e04d4761b33",
  "userId" : "test@domain.com",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "time" : "2020-12-20",
  "total" : 7.11,
  "currency" : "EUR",
  "country" : "FR",
  "billable" : false,
  "state" : "WAITING_FOR_VALIDATION",
  "label" : "Burrito",
  "customFields" : {
    "" : ""
  },
  "createdAt" : "2021-02-19T09:51:20.000000987Z",
  "createdWith" : "api/v1",
  "category" : "lunch",
  "receiptKey" : "test@domain.com/93605f7e-5618-425f-ac02-ef39e4b3ac84.jpg",
  "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
  "totalWithoutTax" : 5.93,
  "taxes" : [ {
    "baseAmount" : 5.93,
    "rate" : 20,
    "amount" : 1.19
  } ],
  "type" : "STANDARD"
}

Look up an expense by its identifier.

Request

GET /api/org/v1/expenses/{expenseId}

Response body

The expense.

See Expense

Create a new expense

curl -X POST "https://api-test.jenji.io/api/org/v1/expenses" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "type" : "STANDARD",
              "time" : "2020-12-20",
              "billable" : false,
              "customFields" : {
                "" : ""
              },
              "taxes" : [ {
                "baseAmount" : 5.93,
                "rate" : 20,
                "amount" : 1.19
              } ],
              "country" : "FR",
              "label" : "Burrito",
              "category" : "lunch",
              "currency" : "EUR",
              "total" : 7.11,
              "totalWithoutTax" : 5.93,
              "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
              "receiptKey" : "test@domain.com/b32f411d-5766-4308-b6ad-d24b31ebd911.jpg",
              "userId" : "test@domain.com",
              "type" : "STANDARD"
            }'
{
  "id" : "251652d1-9de9-4b7e-b890-5e04d4761b33",
  "userId" : "test@domain.com",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "time" : "2020-12-20",
  "total" : 7.11,
  "currency" : "EUR",
  "country" : "FR",
  "billable" : false,
  "state" : "WAITING_FOR_VALIDATION",
  "label" : "Burrito",
  "customFields" : {
    "" : ""
  },
  "createdAt" : "2021-02-19T09:51:20.000000987Z",
  "createdWith" : "api/v1",
  "category" : "lunch",
  "receiptKey" : "test@domain.com/b32f411d-5766-4308-b6ad-d24b31ebd911.jpg",
  "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
  "totalWithoutTax" : 5.93,
  "taxes" : [ {
    "baseAmount" : 5.93,
    "rate" : 20,
    "amount" : 1.19
  } ],
  "type" : "STANDARD"
}
curl -X POST "https://api-test.jenji.io/api/org/v1/expenses?check-missing-custom-fields=true" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "type" : "STANDARD",
              "time" : "2020-12-20",
              "billable" : false,
              "customFields" : { },
              "taxes" : [ {
                "baseAmount" : 5.93,
                "rate" : 20,
                "amount" : 1.19
              } ],
              "country" : "FR",
              "label" : "Burrito",
              "category" : "lunch",
              "currency" : "EUR",
              "total" : 7.11,
              "totalWithoutTax" : 5.93,
              "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
              "receiptKey" : "test@domain.com/41040e72-c313-40f0-a6fc-5169ed01d5ed.jpg",
              "userId" : "test@domain.com",
              "type" : "STANDARD"
            }'
{
  "timestamp" : 1669309467343,
  "error" : "Missing custom field",
  "path" : "/api/org/v1/expenses",
  "errorCode" : "EXP_033",
  "status" : 400
}

Create a new expense, based on the provided expense data.

Request

POST /api/org/v1/expenses

Query parameters

parameter type required description
check-missing-custom-fields Boolean false Enforce presence of all custom fields required for validation (default: false)

Request body

Expense data.

3 variants:

CreateStandardExpense

Creates a new standard expense, with a receipt.

field type description
time LocalDate Mandatory. The day on which the expense occurred (yyyy-MM-dd).
explanation String Optional. Any comment by the user, explaining in what context the expense occurred.
billable Boolean Optional. Whether the expense may be billed to another party.
tags String[] Optional. List of tags selected by the user, to associate to the expense. These tags may be used in graphical agents to search for expenses.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.
taxes Tax[] Optional. Details of the taxes, when taxes apply only on parts of the total amount.
attendees String[] Optional. List of identifiers of organization users who also participated in the event. The current user pays for all of them.
country String Mandatory. Code of the country of the expense, a standard two-letter code in uppercase (e.g.: FR).
label String Mandatory. The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...).
category String Mandatory. The category to which the expense belongs.
currency String Mandatory. Code of the currency of the expense, a standard three-letter code in uppercase (e.g.: EUR).
total BigDecimal Mandatory. The total with taxes reported on the receipt. Note that the amount must have correct decimal places in relation to its currency.
totalWithoutTax BigDecimal Optional. The total without taxes reported on the receipt. Note that the amount must have correct decimal places in relation to its currency.
paymentMethodId String Mandatory. The payment method used by the organization user to pay for the expense. It must be declared on the organization itself.
reimbursable Boolean Optional. Whether the expense may be reimbursed.
receiptKey String Mandatory. The key of the receipt, obtained when uploading the receipt to the Jenji Storage. Once the receipt has been uploaded, it may not be changed.
userId String Mandatory. The user who registers an expense, and expects a reimbursement.
type ExpenseType Mandatory. Type of the expense.

CreateMileageExpense

Creates a new mileage expense, for users traveling for business, with their personal vehicle.

field type description
time LocalDate Mandatory. The day on which the expense occurred (yyyy-MM-dd).
explanation String Optional. Any comment by the user, explaining in what context the expense occurred.
billable Boolean Optional. Whether the expense may be billed to another party.
tags String[] Optional. List of tags selected by the user, to associate to the expense. These tags may be used in graphical agents to search for expenses.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.
label String Mandatory. The description of the travel.
country String Mandatory. Code of the country of the expense, a standard two-letter code in uppercase (e.g.: FR).
reimbursable Boolean Optional. Whether the expense may be reimbursed.
distance BigDecimal Mandatory. The distance travelled by the user. The amount to reimburse is usually calculated with the distance.
computedDistance BigDecimal The distance computed by Google Maps.
distanceUnit DistanceUnit Optional. The distance unit for the mileage, default is KM.
numberOfPassengers Integer Optional. Number of passengers transported by a user, on a trip. Some mileage allowances may include a premium on the amount reimbursed to the user, when there are some passengers.
vehicleId String Mandatory. The identifier of the personal vehicle of the user, defined in his/her profile.
waypoints Waypoint[] Optional. The waypoints describe the different points of the journey made by the user.
total BigDecimal Optional. Amount of the expense, if not null will force the mileage total to this value instead of computing it with Jenji\u2019s system.
userId String Mandatory. The user who registers an expense, and expects a reimbursement.
type ExpenseType Mandatory. Type of the expense.

CreateAllowanceExpense

Creates an expense of type allowance. An allowance is an expense which amount (among other things) is fixed, based on company rules. For instance, one may receive an allowance of 15\u20ac for lunches.

field type description
time LocalDate Mandatory. The day on which the expense occurred (yyyy-MM-dd).
explanation String Optional. Any comment by the user, explaining in what context the expense occurred.
billable Boolean Optional. Whether the expense may be billed to another party.
tags String[] Optional. List of tags selected by the user, to associate to the expense. These tags may be used in graphical agents to search for expenses.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.
taxes Tax[] Optional. Details of the taxes, when taxes apply only on parts of the total amount.
attendees String[] Optional. List of identifiers of organization users who also participated in the event. The current user pays for all of them.
country String Optional. Code of the country of the expense, a standard two-letter code in uppercase (e.g.: FR). May be filled only if the value is not set on the allowance template.
label String Optional. The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...). May be filled only if the value is not set on the allowance template.
category String Optional. The category to which the expense belongs. May be filled only if the value is not set on the allowance template.
paymentMethodId String Optional. The payment method used by the organization user to pay for the expense. It must be declared on the organization itself. May be filled only if the value is not set on the allowance template.
templateId String Mandatory. The identifier of the template used by the allowance to derive default fields on the expense. After the template has been set, it may not be changed.
userId String Mandatory. The user who registers an expense, and expects a reimbursement.
type ExpenseType Mandatory. Type of the expense.

Response body

The newly-created expense.

See Expense

Update an expense

curl -X PUT "https://api-test.jenji.io/api/org/v1/expenses/251652d1-9de9-4b7e-b890-5e04d4761b33" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "type" : "STANDARD",
              "time" : "2020-12-20",
              "billable" : false,
              "customFields" : {
                "" : ""
              },
              "taxes" : [ {
                "baseAmount" : 5.93,
                "rate" : 20,
                "amount" : 1.19
              } ],
              "country" : "FR",
              "label" : "Burrito",
              "category" : "lunch",
              "currency" : "EUR",
              "total" : 7.11,
              "totalWithoutTax" : 5.93,
              "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
              "type" : "STANDARD"
            }'
{
  "id" : "251652d1-9de9-4b7e-b890-5e04d4761b33",
  "userId" : "test@domain.com",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "time" : "2020-12-20",
  "total" : 7.11,
  "currency" : "EUR",
  "country" : "FR",
  "billable" : false,
  "state" : "WAITING_FOR_VALIDATION",
  "label" : "Burrito",
  "customFields" : {
    "" : ""
  },
  "createdAt" : "2021-02-19T09:51:20.000000987Z",
  "createdWith" : "api/v1",
  "category" : "lunch",
  "receiptKey" : "test@domain.com/87cedecd-6f31-4f86-92e5-3e852a7a3e33.jpg",
  "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
  "totalWithoutTax" : 5.93,
  "taxes" : [ {
    "baseAmount" : 5.93,
    "rate" : 20,
    "amount" : 1.19
  } ],
  "type" : "STANDARD"
}

Update the fields of an expense. Updates may only be performed if the state of the expense allows it. This is a PUT request, not a PATCH request: any field left empty will be cleared in the end, so make sure you fill in all fields which should have a value when calling this endpoint.

Request

PUT /api/org/v1/expenses/{expenseId}

Query parameters

parameter type required description
check-missing-custom-fields Boolean false Enforce presence of all custom fields required for validation (default: false)

Request body

Expense data.

3 variants:

UpdateStandardExpense

Updates an existing standard expense. You may not change the receipt for legal reasons: if an organization user has uploaded the wrong receipt, then you must cancel the current expense and re-create a new one.

field type description
time LocalDate Mandatory. The day on which the expense occurred (yyyy-MM-dd).
explanation String Optional. Any comment by the user, explaining in what context the expense occurred.
billable Boolean Optional. Whether the expense may be billed to another party.
tags String[] Optional. List of tags selected by the user, to associate to the expense. These tags may be used in graphical agents to search for expenses.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.
taxes Tax[] Optional. Details of the taxes, when taxes apply only on parts of the total amount.
attendees String[] Optional. List of identifiers of organization users who also participated in the event. The current user pays for all of them.
country String Mandatory. Code of the country of the expense, a standard two-letter code in uppercase (e.g.: FR).
label String Mandatory. The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...).
category String Mandatory. The category to which the expense belongs.
currency String Mandatory. Code of the currency of the expense, a standard three-letter code in uppercase (e.g.: EUR).
total BigDecimal Mandatory. The total with taxes reported on the receipt. Note that the amount must have correct decimal places in relation to its currency.
totalWithoutTax BigDecimal Optional. The total without taxes reported on the receipt. Note that the amount must have correct decimal places in relation to its currency.
paymentMethodId String Mandatory. The payment method used by the organization user to pay for the expense. It must be declared on the organization itself.
reimbursable Boolean Optional. Whether the expense may be reimbursed.
actionUserId String Optional. Identifier of the user who updates the expense. This user must belong to the same organization as the one of the user who declared the expense. If not filled in, then the action maker becomes the user associated to the API token.
type ExpenseType Mandatory. Type of the expense.

UpdateMileageExpense

Updates an existing mileage expense, for users traveling for business, with their personal vehicle.

field type description
time LocalDate Mandatory. The day on which the expense occurred (yyyy-MM-dd).
explanation String Optional. Any comment by the user, explaining in what context the expense occurred.
billable Boolean Optional. Whether the expense may be billed to another party.
tags String[] Optional. List of tags selected by the user, to associate to the expense. These tags may be used in graphical agents to search for expenses.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.
label String Mandatory. The description of the travel.
country String Mandatory. Code of the country of the expense, a standard two-letter code in uppercase (e.g.: FR).
reimbursable Boolean Optional. Whether the expense may be reimbursed.
distance BigDecimal Mandatory. The distance travelled by the user. The amount to reimburse is usually calculated with the distance.
computedDistance BigDecimal The distance computed by Google Maps.
distanceUnit DistanceUnit Optional. The distance unit for the mileage, default is KM.
numberOfPassengers Integer Optional. Number of passengers transported by a user, on a trip. Some mileage allowances may include a premium on the amount reimbursed to the user, when there are some passengers.
vehicleId String Mandatory. The identifier of the personal vehicle of the user, defined in his/her profile.
waypoints Waypoint[] Optional. The waypoints describe the different points of the journey made by the user.
total BigDecimal Optional. Amount of the expense, if not null will force the mileage total to this value instead of computing it with Jenji\u2019s system.
actionUserId String Optional. Identifier of the user who updates the expense. This user must belong to the same organization as the one of the user who declared the expense. If not filled in, then the action maker becomes the user associated to the API token.
type ExpenseType Mandatory. Type of the expense.

UpdateAllowanceExpense

Updates an expense of type allowance. You may not change the underlying template after an expense has been created.

field type description
time LocalDate Mandatory. The day on which the expense occurred (yyyy-MM-dd).
explanation String Optional. Any comment by the user, explaining in what context the expense occurred.
billable Boolean Optional. Whether the expense may be billed to another party.
tags String[] Optional. List of tags selected by the user, to associate to the expense. These tags may be used in graphical agents to search for expenses.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.
taxes Tax[] Optional. Details of the taxes, when taxes apply only on parts of the total amount.
attendees String[] Optional. List of identifiers of organization users who also participated in the event. The current user pays for all of them.
country String Optional. Code of the country of the expense, a standard two-letter code in uppercase (e.g.: FR). May be filled only if the value is not set on the allowance template.
label String Optional. The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...). May be filled only if the value is not set on the allowance template.
category String Optional. The category to which the expense belongs. May be filled only if the value is not set on the allowance template.
paymentMethodId String Optional. The payment method used by the organization user to pay for the expense. It must be declared on the organization itself. May be filled only if the value is not set on the allowance template.
actionUserId String Optional. Identifier of the user who updates the expense. This user must belong to the same organization as the one of the user who declared the expense. If not filled in, then the action maker becomes the user associated to the API token.
type ExpenseType Mandatory. Type of the expense.

Response body

The updated expense.

See Expense

List workflow actions

curl -X GET "https://api-test.jenji.io/api/org/v1/expenses/251652d1-9de9-4b7e-b890-5e04d4761b33/actions" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ "accept", "reject" ]
}

Request

GET /api/org/v1/expenses/{expenseId}/actions

Response body

List of possible actions for the specified expense. The action user must however have access to a profile authorized to perform the action, for the change of state to succeed.

field type description
data String[]

Execute workflow action

curl -X POST "https://api-test.jenji.io/api/org/v1/expenses/251652d1-9de9-4b7e-b890-5e04d4761b33/actions/accept" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "actionUserId" : "manager-id"
            }'
{
  "id" : "251652d1-9de9-4b7e-b890-5e04d4761b33",
  "userId" : "test@domain.com",
  "organizationId" : "b48f8a89-e467-4b93-9aa4-196bd64c796a",
  "time" : "2020-12-20",
  "total" : 7.11,
  "currency" : "EUR",
  "country" : "FR",
  "billable" : false,
  "state" : "ACCEPTED",
  "label" : "Burrito",
  "customFields" : {
    "" : ""
  },
  "createdAt" : "2021-02-19T09:51:20.000000987Z",
  "createdWith" : "api/v1",
  "category" : "lunch",
  "receiptKey" : "test@domain.com/08ff956a-b298-425b-85ff-6356ad9d5782.jpg",
  "paymentMethodId" : "c3155ca8-4335-4b34-b135-bf26d064fa07",
  "totalWithoutTax" : 5.93,
  "taxes" : [ {
    "baseAmount" : 5.93,
    "rate" : 20,
    "amount" : 1.19
  } ],
  "type" : "STANDARD"
}

Change the state of an expense by triggering a workflow action.
You must specify an action code, which indicates the action to perform on the expense, like "validate", "refuse" and so on.
Available action codes depend on the workflow configured for the organization, the expense state and the profiles of the requesting user.

Request

POST /api/org/v1/expenses/{expenseId}/actions/{actionCode}

Path variables

parameter type required description
actionCode String true

Request body

The action execution request.

field type description
actionUserId String Optional. Identifier of the user who makes the action on the expense. This user must belong to the same organization as the one of the user who declared the expense. If not filled in, then the action maker becomes the user associated to the API token.
comment String Any comment related to the change of state.

Response body

The updated expense.

See Expense

Delete an expense

curl -X DELETE "https://api-test.jenji.io/api/org/v1/expenses/251652d1-9de9-4b7e-b890-5e04d4761b33" \
     -u API_USER_ID:SECRET_KEY \
null

Delete an expense. This passes the expense into the DELETED state, resulting in it being excluded from all expense-related operating processes.

Request

DELETE /api/org/v1/expenses/{expenseId}

Get the url to upload a receipt

# openssl md5 -binary invoice.pdf | base64
# yaWmh42XtIzJZcHkGFnwNA==
curl -X POST "https://api-test.jenji.io/api/org/v1/receipts/upload-url" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "fileType" : "pdf",
              "userId" : "my-user-id",
              "md5" : "yaWmh42XtIzJZcHkGFnwNA==",
              "receiptType" : "EXPENSE"
            }'
{
  "uploadUrl" : "https://scanny-incoming-pdf.s3.eu-west-1.amazonaws.com/my-user-id/ab6178a0-c705-48ee-a16a-b4ad102b5797.pdf?X-Amz-Security-Token=FwoGZXIvYL%2BESkskIdq9SjfsyCLIAWVQmmZLEay7h7wO2jr4IQqk8oKQejhmgs5Vhm8DWPcd%2Bqv705M5KIgRKFj2ohJHjo7rZloOO6pap65mMFGGbxjSIlRvHewN82w46qhrf7vtgrruK3cZXiUpq5fMTS5VnDGFMaN%2FelTpMq7Gfi5C4%2FMjI51P840ufulxXgJ0mc%2BVm7O9E41J1nHm6s3uwqisySZnqY91CLKl5%2BiikCyz%2Behlk%2B4H%2Bk4UrwbeiZL4QigR4wDU0GsB4Y8f9PJE1uyxI3h9Xxua1fMkKKycuosGMi333qVyXqE71pwlPua%2FEvTIHDfzXfSfLMrz1e2I406btm4cS3vuL0Vs8ofHXAw%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20211019T092833Z&X-Amz-SignedHeaders=content-md5%3Bhost&X-Amz-Expires=600&X-Amz-Credential=ASIAV5IPOSXFZ365H%2F20211019%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Signature=0ad5bc393b41e0540f1e9864c29f2b45b9923abc8c145d6043c94380a9cfcd",
  "key" : "my-user-id/ab6178a0-c705-48ee-a16a-b4ad102b5797.pdf"
}
# Upload file via returned url
curl -X PUT --data-binary "@invoice.pdf" -H "Content-MD5: yaWmh42XtIzJZcHkGFnwNA==" https://scanny-incoming-pdf.s3.eu-west-1.amazonaws.com/my-user-id/ab6178a0-c705-48ee-a16a-b4ad102b5797.pdf?X-Amz-Security-Token=FwoGZXIvYL%2BESkskIdq9SjfsyCLIAWVQmmZLEay7h7wO2jr4IQqk8oKQejhmgs5Vhm8DWPcd%2Bqv705M5KIgRKFj2ohJHjo7rZloOO6pap65mMFGGbxjSIlRvHewN82w46qhrf7vtgrruK3cZXiUpq5fMTS5VnDGFMaN%2FelTpMq7Gfi5C4%2FMjI51P840ufulxXgJ0mc%2BVm7O9E41J1nHm6s3uwqisySZnqY91CLKl5%2BiikCyz%2Behlk%2B4H%2Bk4UrwbeiZL4QigR4wDU0GsB4Y8f9PJE1uyxI3h9Xxua1fMkKKycuosGMi333qVyXqE71pwlPua%2FEvTIHDfzXfSfLMrz1e2I406btm4cS3vuL0Vs8ofHXAw%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20211019T092833Z&X-Amz-SignedHeaders=content-md5%3Bhost&X-Amz-Expires=600&X-Amz-Credential=ASIAV5IPOSXFZ365H%2F20211019%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Signature=0ad5bc393b41e0540f1e9864c29f2b45b9923abc8c145d6043c94380a9cfcd

Get the url to upload the receipt of an expense.

You need to compute the md5 of the file, then encode according to https://aws.amazon.com/premiumsupport/knowledge-center/data-integrity-s3/.

For java implementation:

Later on, you will need to provide the MD5 hash as a header when calling the upload URL with your receipt: curl -X PUT --data-binary @path_to_your_receipt -H "Content-MD5: UiDXFTZBDEg0eA6vVUm1Zg==" {the_upload_url}

Request

POST /api/org/v1/receipts/upload-url

Request body

Get the url to upload the receipt of an expense into Jenji Storage.

field type description
fileType String Mandatory. The file extension, one of "jpg", "jpeg", "pdf".
userId String Mandatory. The identifier of the user emitting the expense, awaiting reimbursement.
md5 String Mandatory. Encoded MD5 hash of your receipt
receiptType ReceiptType Optional. Receipt type: EXPENSE (default) or EXPENSE_REQUEST

Response body

A secure URL to where a receipt may be uploaded, as well as a technical key pointing to the location, to be referenced into the expense. This URL remains valid for a few minutes only.

See ReceiptUpload

ReceiptType

value description
EXPENSE
EXPENSE_REQUEST

Get the url to download the receipt of an expense

curl -X POST "https://api-test.jenji.io/api/org/v1/expenses/251652d1-9de9-4b7e-b890-5e04d4761b33/receipts/download-url" \
     -u API_USER_ID:SECRET_KEY \
{
  "downloadUrl" : "https://scanny.s3.eu-west-1.amazonaws.com/victor.clogenson%2Be1r20%40jenji.io/c749ff23-122f-4a17-81fd-97de17690d41.jpg?X-Amz-Security-Token=FwoGZXIvYXdzECsaDHhkrZ9CiSl38zJyETWhwsB9Igs3yg04EhM%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20211119T093608Z&X-Amz-SignedHeaders=host&X-Amz-Expires=599&X-Amz-Credential=ASIAV5IU6VPOTBN3QU2D%2F20211119%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Signature=e4a946de0af7ac04dfce77dd438"
}

Get the url to download the receipt of an expense.

Request

POST /api/org/v1/expenses/{expenseId}/receipts/download-url

Response body

A secure URL from which the receipt of an expense may be downloaded. This URL remains valid for a few minutes only.

See ReceiptDownload

Get expense warnings

curl -X GET "https://api-test.jenji.io/api/org/v1/expenses/a31bbb40-dae0-4073-b250-4f13823b4611/warnings" \
     -u API_USER_ID:SECRET_KEY \
{
  "data" : [ {
    "warningRuleId" : "8ff59840-30d3-46c6-95d6-f2dd0f010224",
    "userId" : "3cccabdc-ba89-4ade-86a9-2f9bc4addaff",
    "time" : "2020-12-24",
    "updatedAt" : "2022-11-24T17:04:27.372992Z",
    "code" : "m30"
  } ]
}

Return all warnings of an expense

Request

GET /api/org/v1/expenses/{expenseId}/warnings

Response body

field type description
data ExpenseWarning[]
data[].warningRuleId String The identifier of the warning rule. Either the identifier of a custom rule (a UUID), or a reserved rule identifier (e.g. "duplicate").
data[].userId String Identifier of the user who own the warning (user of the targeted expense)
data[].time LocalDate Day on which the expense owning the warning occurred.
data[].updatedAt OffsetDateTime Timestamp of the update of the warning.
data[].code String The custom code chosen when creating the warning rule.
data[].labelsPerLanguage Map<String,String> Custom labels for the warning, by language code.

Custom labels are optional, they are only set for warnings generated by certain warning rules. When missing, default labelling algorithms should be applied, e.g. derive appropriate labels from the warning code, or from the default labels of the associated warning rule.

data[].isPreventingValidation Boolean Indicates whether this warning should prevent the validation of the expense/request or not
data[].mutedAt OffsetDateTime Timestamp of the muting of the warning.
data[].mutedBy String Identifier of the user who has muted the warning.
data[].linkedExpensesIds String[] Identifiers of the expenses that are related to the warning.

Add a warning to an Expense

curl -X PUT "https://api-test.jenji.io/api/org/v1/expenses/a31bbb40-dae0-4073-b250-4f13823b4611/warnings/8ff59840-30d3-46c6-95d6-f2dd0f010224" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "code" : "m30"
            }'
{
  "warningRuleId" : "8ff59840-30d3-46c6-95d6-f2dd0f010224",
  "userId" : "3cccabdc-ba89-4ade-86a9-2f9bc4addaff",
  "time" : "2020-12-24",
  "updatedAt" : "2022-11-24T17:04:27.375078Z",
  "code" : "m30"
}

Add a warning to an expense. Rule must exist.

The warning rule ID path parameter can only refer to a warning rule that was previously created by API (= type EXTERNAL). Internal Jenji warning rule ID cannot be used here !

You can either provide the Jenji ID, that was returned by the Warning rule creation API, or the external rule ID if you provided one on Warning rule creation API call. To provide an external rule ID, use the format 'ext-your-warning-rule-id'.

Request

PUT /api/org/v1/expenses/{expenseId}/warnings/{warningRuleId}

Path variables

parameter type required description
warningRuleId String true can be either Jenji ID or an external ID using the format 'ext-your-warning-rule-id'

Request body

field type description
code String For rules with multiple options, the code is required and must be one of the rule code

Response body

An expense warning describes a custom rule to be applied to an expense, to check some of its state. For instance, a "duplicate" warning tells when 2 expenses of the same amount are created on the same day.

See ExpenseWarning

Remove a warning from an expense

curl -X DELETE "https://api-test.jenji.io/api/org/v1/expenses/a31bbb40-dae0-4073-b250-4f13823b4611/warnings/8ff59840-30d3-46c6-95d6-f2dd0f010224" \
     -u API_USER_ID:SECRET_KEY \
null

Delete a warning from an expense. Rule must exist.

The warning rule ID path parameter can only refer to a warning rule that was previously created by API (= type EXTERNAL). Internal Jenji warning rule ID cannot be used here !

You can either provide the Jenji ID, that was returned by the Warning rule creation API, or the external rule ID if you provided one on Warning rule creation API call. To provide an external rule ID, use the format 'ext-your-warning-rule-id'.

Request

DELETE /api/org/v1/expenses/{expenseId}/warnings/{warningRuleId}

Path variables

parameter type required description
warningRuleId String true can be either Jenji ID or an external ID using the format 'ext-your-warning-rule-id'

Get export ids

curl -X GET "https://api-test.jenji.io/api/org/v1/expenses/26f1c5a6-a242-457d-be51-ea4a5b2b65d3/exports" \
     -u API_USER_ID:SECRET_KEY \
{
  "expenseId" : "26f1c5a6-a242-457d-be51-ea4a5b2b65d3",
  "accounting" : "354e40d2-6030-4b0b-88e8-43131a99795a",
  "payroll" : "63a6014b-aa34-4efe-bc3c-a0a7d147dc35"
}

Return the accounting an payroll export identifiers containing the expenses

Request

GET /api/org/v1/expenses/{expenseId}/exports

Response body

Contains ids of exports containing expense

field type description
expenseId String Expense identified
accounting String Accounting export identifier
payroll String Payroll export identifier

Delete accounting export

curl -X DELETE "https://api-test.jenji.io/api/org/v1/expenses/26f1c5a6-a242-457d-be51-ea4a5b2b65d3/exports/accounting" \
     -u API_USER_ID:SECRET_KEY \
null
curl -X DELETE "https://api-test.jenji.io/api/org/v1/expenses/26f1c5a6-a242-457d-be51-ea4a5b2b65d3/exports/payroll" \
     -u API_USER_ID:SECRET_KEY \
null

Delete the specified export information of the expense

Request

DELETE /api/org/v1/expenses/{expenseId}/exports/{exportType}

Path variables

parameter type required description
exportType String true accounting or payroll

Expense Requests

Set of methods to search expense requests. These methods may only be called by the organization for its own expense requests, or by its bookkeeper.

Search expense requests of your organization

Search for expense requests of your own organization (as a root admin), according to specified criteria.

Request

POST /api/org/v1/expense-requests/search

Request body

The criteria to search for.

field type description
start LocalDate Mandatory. Inclusive start of the search interval as a local date (YYYY-MM-DD).
end LocalDate Mandatory. Inclusive end of the search interval as a local date (YYYY-MM-DD).
states String[] Optional. List of states to match when searching expenses. Theses states are configured in workflow states, contact support for possibles values.

Response body

List of expense requests matching the search criteria.

field type description
data ExpenseRequest[]
data[].id String Unique identifier of the expense request in Jenji (a UUID).
data[].shortId String Unique short Id identifier
data[].label String Label of expense request
data[].type String Type of expense request
data[].userId String Unique identifier of the organization user for which the expense request applies (either an email or a UUID, depending on the acquisition channel).
data[].state String State of the expense request
data[].comment String Explanation for the expense expense request, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
data[].expenses String[] Expenses Id of linked expenses.
data[].creationDate OffsetDateTime Creation date of expense Request.
data[].customFields Map<String,Object> Custom fields are defined by organizations, to help classify an expense request for analytic purposes. This fields maps values for all required custom fields.
data[].files ExpenseRequestFile[] Expense request attached files.

Create expense request

Create a new expense request.

Request

POST /api/org/v1/expense-requests

Request body

Expense request data.

field type description
label String Mandatory. Label of expense request
type String Mandatory. Type of expense request. Accepted values depends of your organization configuration
userId String Mandatory. Unique identifier of the organization user for which the expense request applies (either an email or a UUID, depending on the acquisition channel).
comment String Optional. Explanation for the expense expense request, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
files NamedFile[] Optional. Request files.
files[].name String Real file name (displayed in UX).
files[].file String File reference in Jenji storage system.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.

Response body

Created expense request.

See ExpenseRequest

Get expense request

Get an expense request.

Request

GET /api/org/v1/expense-requests/{requestId}

Response body

Expense request.

See ExpenseRequest

Update expense request

Update an expense request. All data will be overwrite by input. If you need to make a partial update, use the patch request.

Request

PUT /api/org/v1/expense-requests/{requestId}

Path variables

parameter type required description
requestId String true Expense request id.

Request body

field type description
label String Mandatory. Label of expense request
comment String Optional. Explanation for the expense expense request, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
files NamedFile[] Optional. Request files.
files[].name String Real file name (displayed in UX).
files[].file String File reference in Jenji storage system.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.

Response body

Updated expense request.

See ExpenseRequest

Patch expense request

Patch an expense request. Only non null value sent will be used. Files in body will be added to the request, renamed id the same file, and no files will be removed.

Request

PATCH /api/org/v1/expense-requests/{requestId}

Path variables

parameter type required description
requestId String true Expense request id.

Request body

field type description
label String Mandatory. Label of expense request
comment String Optional. Explanation for the expense expense request, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
files NamedFile[] Optional. Request files.
files[].name String Real file name (displayed in UX).
files[].file String File reference in Jenji storage system.
customFields Map<String,Object> Optional. Map of custom field values, by custom field code. You must ensure that the type of the custom field value is consistent with the type of the custom field definition, recorded on the organization.

Response body

Updated expense request.

See ExpenseRequest

List workflow actions

Request

GET /api/org/v1/expense-requests/{requestId}/actions

Response body

List of possible actions for the specified request.

field type description
data String[]

Execute workflow action

Change the state of an request by triggering a workflow action.
You must specify an action code, which indicates the action to perform on the request.
Available action codes depend on the workflow configured for the organization, the request state.

Request

POST /api/org/v1/expense-requests/{requestId}/actions/{actionCode}

Path variables

parameter type required description
actionCode String true

Request body

The action execution request.

field type description
actionUserId String Optional. Identifier of the user who makes the action on the request. This user must belong to the same organization as the one of the user who declared the request. If not filled in, then the action maker becomes the user associated to the API token.
comment String Any comment related to the change of state.

Response body

The updated expense.

See ExpenseRequest

Bookkeepers

Set of methods to create, update or view bookkeepers. These methods may only be used by a master bookkeeper, or by the bookkeeper of which it is question.

List all bookkeepers

A master bookkeeper retrieves the list of all bookkeepers which he/she is allowed to manage.

Request

GET /api/bk/v1/bookkeepers

Response body

List of the bookkeepers managed by the master bookkeeper.

field type description
data Bookkeeper[]
data[].id String Unique identifier of the bookkeeper in Jenji (a UUID).
data[].name String The name of the company.
data[].jenjiOrganizationId String The bookkeeper may also use Jenji as a service for the management of its own expenses. If so, this field contains the identifier of its Jenji organization.
data[].masterBookkeeperId String This field contains the identifier of the master bookkeeper which manages the bookkeeper, if there is one. The master bookkeeper may perform most operations in the name of its managed bookkeeper.
data[].clientOptions BookkeeperClientOptions Newly-added clients are declared with default options, which are reported below. To date, these options may not be changed by API, but only through our Support.
data[].groups BookkeeperGroup[] The hierarchy of groups of the bookkeeper (each group represents an operational team of the bookkeeper). The top group is named "root group", it is the default group and it may not be deleted.
data[].createdAt OffsetDateTime Timestamp of creation of the bookkeeper.
data[].updatedAt OffsetDateTime Timestamp of last update of the bookkeeper. This timestamp is updated if any header data, or data of the root group, are modified. It is not updated if a subgroup has changed.

View a bookkeeper

Retrieve detailed data of a bookkeeper.

Request

GET /api/bk/v1/bookkeepers/{bookkeeperId}

Response body

Detailed information of a bookkeeper.

See Bookkeeper

Create a new bookkeeper

A master bookkeeper creates a new bookkeeper, and gains access to it. The data used to create that bookkeeper are partly provided by the caller, and partly retrieved from a template specified by the caller.

Request

POST /api/bk/v1/bookkeepers

Request body

Contains the custom bookkeeper data, as well as the template to use.

field type description
name String Mandatory.The company name of the bookkeeper to be created.
templateId String Mandatory. The identifier of a bookkeeper template (a UUID), used to populate the default values of the bookkeeper. You must use one of the template identifiers which was provided to you by our Ops.

Response body

The newly-created bookkeeper, with a unique ID.

See Bookkeeper

Update an existing bookkeeper

Modified header data of a bookkeeper. The data originally filled from a template may not be modified, only the custom data may be changed.

Request

PUT /api/bk/v1/bookkeepers/{bookkeeperId}

Request body

The custom data to update.

field type description
name String Mandatory. The name of the bookkeeper group, e.g. the designation of the team.

Response body

The bookkeeper, with updated data.

See Bookkeeper

Create a new group

Add a new group to a bookkeeper. The caller may specify a parent group to form a hierarchy, or leave the parent null, in which case the group will be created as a direct child of the root group.

Request

POST /api/bk/v1/bookkeepers/{bookkeeperId}/groups

Request body

Data used to create the new group.

field type description
name String Mandatory. The name of the bookkeeper group, e.g. the designation of the team.
parentGroupId String Optional. The parent group of the group to be created. If left empty, then the group parent is automatically set to the bookkeeper root group.

Response body

The newly-created group. To see the entire hierarchy, make a GET on the bookkeeper itself.

See BookkeeperGroup

List all clients

Retrieve the list of clients of a specific bookkeeper.

Request

GET /api/bk/v1/bookkeepers/{bookkeeperId}/clients

Response body

List of the organizations managed by the bookkeeper.

field type description
data BookkeeperClient[]
data[].bookkeeperId String The identifier of bookkeeper party.
data[].organizationId String The identifier of organization managed by the bookkeeper.
data[].internalId String Optional field, an internal id for the contract in the bookkeeper information system.
data[].explanation String Optional field, any form of comment from the bookkeeper to clarify the nature of the contract, or any worthwhile information to pay attention to.

Create a new client

A new organization is created and referenced as client for a bookkeeper. The data used to create that organization are partly provided by the caller, and partly retrieved from a template specified by the caller.

Request

POST /api/bk/v1/bookkeepers/{bookkeeperId}/clients

Request body

Contains the custom organization data, as well as the template to use.

field type description
name String Mandatory. The company name of the organization to be created.
internalId String Optional. The identifier of the organization, as declared in the information system of the bookkeeper.
explanation String Optional. Any informative comment by the bookkeeper about this client. May be be retrieved and displayed to bookkeeper users.
templateId String Mandatory. The identifier of an organization template (a UUID), used to populate the default values of the organization. You must use one of the template identifiers which was provided to you by our Ops.

Response body

The newly-created organization, attached to the bookkeeper, with a unique ID.

See BookkeeperClient

Add states to a client

Add states to an client.

Request

PUT /api/bk/v1/bookkeepers/{bookkeeperId}/clients/{clientId}/states

Request body

Data representing states to add to the client.

field type description
states String[] List of states you wish to add or remove from a client. From:
  • BLOCKED: Blocks all user of the organization, depending on other states, they might be blocked on the dashboard or the billing page.
  • INVALID_PAYMENT: Displays a message to users to warn them that due payment is invalid.

Response body

The updated organization.

field type description

Remove states from an client

Remove states from a client.

Request

DELETE /api/bk/v1/bookkeepers/{bookkeeperId}/clients/{clientId}/states

Request body

Data representing the states to remove from the client.

field type description
states String[] List of states you wish to add or remove from a client. From:
  • BLOCKED: Blocks all user of the organization, depending on other states, they might be blocked on the dashboard or the billing page.
  • INVALID_PAYMENT: Displays a message to users to warn them that due payment is invalid.

Response body

The updated organization.

field type description

Apply template to a client

Apply the configuration of a new template on an organization.

All expenses will be hard reset, only the following attributes will be kept:

Custom profiles will be overridden.
Expense workflows will be overridden.
Expense request workflows will be overridden.

Accounting configurations will be kept.
Warning rules will be kept.

The configuration of the template will be applied to the target client organization.
The following organization's attributes will be overridden, if present in the template configuration:

It also allows to update the accounting configuration.

Changing the accounting template will change accounting export format, columns, ... However, specific organization configuration like account number mappings will not be updated.

Request

POST /api/bk/v1/bookkeepers/{bookkeeperId}/clients/{clientId}/apply-template

Request body

Data representing the template to apply to the client, at least one attribute is required.

field type description
templateId String Identifier of the template to apply. Format: UUID v4.
If null, no modification will be done on organization.
accountingTemplateId String Identifier of the accounting template to apply. Format: UUID v4.
If null, no modification will be done on accounting configuration.

Response body

Details of the updated organization.

See Organization

List all users

List all bookkeeper users of a specific bookkeeper.

Request

GET /api/bk/v1/bookkeepers/{bookkeeperId}/users

Response body

List of bookkeeper users for the bookkeeper.

field type description
data BookkeeperUser[]
data[].id String Unique identifier of the User in Jenji (UUID or email, depending on the original registration channel).
data[].bookkeeperId String Unique identifier of the bookkeeper to which the user belongs.
data[].groupId String Unique identifier of the group of the bookkeeper to which the user belongs.
data[].internalId String Optional field, containing the internal identifier of the user in the information system of the bookkeeper. This may help when querying the APIs and performing various mapping tasks.
data[].firstName String First name of the user, like "Alex" in "Alex Pence".
data[].lastName String Last name of the user, like "Pence" in "Alex Pence".
data[].updatedAt OffsetDateTime Timestamp of the last update of the user.
data[].createdAt OffsetDateTime Timestamp of the creation of the user.
data[].blockedAt OffsetDateTime Timestamp of the blocking of the user. This field is null when the user is not blocked.

Create a new user

Create a new bookkeeper user and adds it to a specific group of the bookkeeper.

Request

POST /api/bk/v1/bookkeepers/{bookkeeperId}/users

Request body

The data required to create the user.

field type description
firstName String Optional. First name of the user, like "Alex" in "Alex Pence".
lastName String Optional. Last name of the user, like "Pence" in "Alex Pence".
groupId String Optional. Identifier of the bookkeeper group to which the user must be added. If left empty, then the user will be attached to the root group of the bookkeeper.
internalId String Optional. Identifier of the user in the information system of the bookkeeper.

Response body

The newly-created user, with a unique ID.

See BookkeeperUser

Update template categories

Update the list of categories for a template.
If the template belongs to the bookkeeper, it will be updated directly with the new categories. If instead the template belongs to the master bookkeeper, the template will be untouched and the categories will override that of the template only in the context of this bookkeeper.
New organizations created from this template after this change will use the updated list of categories.

Existing organizations will be updated asynchronously inside of a 24h window. Multiple successive updates to a same template will effectively be squashed as a unique update for existing organizations. Existing categories that are not present in the new template will NOT be deleted but will be disabled instead to preserve global data consistency (such as expenses referencing those categories).

Request

POST /api/bk/v1/bookkeepers/{bookkeeperId}/templates/{templateId}/categories

Path variables

parameter type required description
templateId String true Id of an existing template.

Request body

The desired complete list of categories for this template.

See Category

Response body

The actual list of categories computed for the template. This list can differ for the input list in case default categories have been omitted. In such a scenario, default categories are set as disabled.

field type description

Update vault configuration

# Enable a 20Go vault on organization
curl -X PUT "https://api-test.jenji.io/api/org/v1/bookkeepers/38f4c549-c430-444d-ad66-281b4f0e9c14/organizations/3a2d464f-ecde-4192-a0e9-3d826fcf52da/vault" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "enabled" : true,
              "capacity" : 20
            }'
{
  "maxCapacity" : 20,
  "consumedCapacity" : 0
}
# Disable vault on organization
curl -X PUT "https://api-test.jenji.io/api/org/v1/bookkeepers/38f4c549-c430-444d-ad66-281b4f0e9c14/organizations/3a2d464f-ecde-4192-a0e9-3d826fcf52da/vault" \
     -u API_USER_ID:SECRET_KEY \
     -H "Content-Type: application/json" \
     --data '{
              "enabled" : false
            }'
{
  "message" : "Vault disabled"
}

Request

PUT /api/org/v1/bookkeepers/{bookkeeperId}/organizations/{organizationId}/vault

Path variables

parameter type required description
organizationId String true

Request body

field type description
enabled Boolean Mandatory. Whether the vault should be enabled or not.
capacity Long The desired vault capacity, in Mb

Response body

field type description
maxCapacity BigDecimal The maximum capacity, in Mb
consumedCapacity BigDecimal The consumed capacity, in Mb. Note that it is only recomputed several times a day.
message String Explanation message, if necessary

Get consumed/max vault capacities

curl -X GET "https://api-test.jenji.io/api/org/v1/bookkeepers/38f4c549-c430-444d-ad66-281b4f0e9c14/organizations/3a2d464f-ecde-4192-a0e9-3d826fcf52da/vault" \
     -u API_USER_ID:SECRET_KEY \
{
  "maxCapacity" : 20,
  "consumedCapacity" : 11.42
}

Request

GET /api/org/v1/bookkeepers/{bookkeeperId}/organizations/{organizationId}/vault

Path variables

parameter type required description
organizationId String true

Response body

field type description
maxCapacity BigDecimal The maximum capacity, in Mb
consumedCapacity BigDecimal The consumed capacity, in Mb. Note that it is only recomputed several times a day.
message String Explanation message, if necessary

Misc

Set of utility methods to perform cross-domain mileage computations. May only be used by an organization.

Compute addresses point

Geocode addresses and get geo positions.

Request

POST /api/tools/v1/tools/mileage/address

Request body

The coordinates of the waypoints.

field type description
startAddress String Optional. Start address of the trip. If missing, then start longitude and latitude must be filled.
startLongitude BigDecimal Optional. Start longitude of the trip ([-180.0; +180.0]).
startLatitude BigDecimal Optional. Start latitude of the trip ([-90.0; +90.0]).
endAddress String Optional. End address of the trip. If missing, then end longitude and latitude must be filled.
endLongitude BigDecimal Optional. End longitude of the trip ([-180.0; +180.0]).
endLatitude BigDecimal Optional. End latitude of the trip ([-90.0; +90.0]).
roundTrip Boolean Optional. Whether this was a round trip; if yes, the returned distance will be multiplied by two. Only applicable if no waypoints have been defined.
waypoints Waypoint[] Optional. Waypoints located between the origin and the destination. Can only have up to 10 waypoints.

Response body

The computed distance.

field type description
start Place
start.area1 String
start.area2 String
start.country String
start.externalId String
start.formattedAddress String
start.latitude BigDecimal
start.locality String
start.longitude BigDecimal
start.postalCode String
start.postalTown String
start.postBox String
start.provider PlaceProvider
start.query String
start.route String
start.streetAddress String
start.streetNumber String
end Place
end.area1 String
end.area2 String
end.country String
end.externalId String
end.formattedAddress String
end.latitude BigDecimal
end.locality String
end.longitude BigDecimal
end.postalCode String
end.postalTown String
end.postBox String
end.provider PlaceProvider
end.query String
end.route String
end.streetAddress String
end.streetNumber String

PlaceProvider

value description
GOOGLE

Compute trip distance

Computes the distance of a simple trip, with two waypoints.

Request

POST /api/tools/v1/tools/mileage/trip

Request body

The coordinates of the waypoints.

field type description
startAddress String Optional. Start address of the trip. If missing, then start longitude and latitude must be filled.
startLongitude BigDecimal Optional. Start longitude of the trip ([-180.0; +180.0]).
startLatitude BigDecimal Optional. Start latitude of the trip ([-90.0; +90.0]).
endAddress String Optional. End address of the trip. If missing, then end longitude and latitude must be filled.
endLongitude BigDecimal Optional. End longitude of the trip ([-180.0; +180.0]).
endLatitude BigDecimal Optional. End latitude of the trip ([-90.0; +90.0]).
roundTrip Boolean Optional. Whether this was a round trip; if yes, the returned distance will be multiplied by two. Only applicable if no waypoints have been defined.
waypoints Waypoint[] Optional. Waypoints located between the origin and the destination. Can only have up to 10 waypoints.

Response body

The computed distance.

See TripDistance

Shared resources

Advance imputation

When an expense is reimbursed to the user, some part of the reimbursable amount may have been paid already, in the form of advances provisioned by the organization to the user. This object helps track such pre-payments.

field type description
advanceId String The unique identifier of the advance provisioned by the organization to the user. An advance may be used to reimburse one or many expenses (if it is large enough).
imputedAmount BigDecimal The amount imputed on the advance for this expense. For instance, if the user has been allocated an advance of 30\u20ac and now issues an expense of 10\u20ac, then the advance will be imputed for 10\u20ac (20\u20ac will remain available for other expenses).

Expressed in the reimbursement currency, usually the master currency of the organization.

AllowanceTemplate

Allowance template will be provided as a way to create an allowance, which is an expense with values filled from template at creation and not updatable after (like name, total, category, ...).

User will be able to update expense time, explanation, custom fields, ...

Values are copied on expense creation, updating a template after will not affect existing expenses.

field type description
templateId String Template id, value must be passed when creating an allowance expense.
labelsPerLanguage Map<String,String> The labels of the allowance template, per language, as displayed to front clients (web application, mobile applications).
total BigDecimal The total amount of the allowance.
currency String The currency of the total amount. (EUR, USD, ...)
country String The country of the expense. (FR, US, ...)
category String The category of the expense.
paymentMethodId String The identifier of the payment method which was used to pay the expense (for instance a credit card). Payment methods are declared on the groups of the organization.
order int Template order in the front selection list.
disabled Boolean Disable the template, making creation of new expense from it impossible.
requireReceipt Boolean User must add a receipt with the allowance (default false). If no receipt is required, the category icon will be used instead.
creationCondition ScopeCondition Allow to manage the availability of the template for the users, using advanced conditions

Bookkeeper

A bookkeeper is an accounting company, which manages the accounts of client companies, such as liberal professionals. It is structured into a hierarchy of bookkeeper groups, each group representing an operational team of the bookkeeper. Most of the time, a bookkeeper only needs a single team, i.e. the default root group.

field type description
id String Unique identifier of the bookkeeper in Jenji (a UUID).
name String The name of the company.
jenjiOrganizationId String The bookkeeper may also use Jenji as a service for the management of its own expenses. If so, this field contains the identifier of its Jenji organization.
masterBookkeeperId String This field contains the identifier of the master bookkeeper which manages the bookkeeper, if there is one. The master bookkeeper may perform most operations in the name of its managed bookkeeper.
clientOptions BookkeeperClientOptions Newly-added clients are declared with default options, which are reported below. To date, these options may not be changed by API, but only through our Support.
groups BookkeeperGroup[] The hierarchy of groups of the bookkeeper (each group represents an operational team of the bookkeeper). The top group is named "root group", it is the default group and it may not be deleted.
createdAt OffsetDateTime Timestamp of creation of the bookkeeper.
updatedAt OffsetDateTime Timestamp of last update of the bookkeeper. This timestamp is updated if any header data, or data of the root group, are modified. It is not updated if a subgroup has changed.

BookkeeperClient

A bookkeeper may manage the expenses of an organization. In such a case, the organization becomes the client of the bookkeeper, and this entity represents the link between the bookkeeper and the organization, as well as its characteristics.

field type description
bookkeeperId String The identifier of bookkeeper party.
organizationId String The identifier of organization managed by the bookkeeper.
internalId String Optional field, an internal id for the contract in the bookkeeper information system.
explanation String Optional field, any form of comment from the bookkeeper to clarify the nature of the contract, or any worthwhile information to pay attention to.

BookkeeperClientOptions

Technical options associated to a client of a bookkeeper.

These options are currently readonly (contact our Support if you want to change them). They are defined in the organization template chosen by the bookkeeper when creating a new client.

field type description
clientsBilledByJenji boolean The activity of an organization (expense management...) is billed by Jenji, either to the bookkeeper, or to the organization itself. If set to true, then the organization is billed directly.
manageClientVault boolean Jenji offers a Vault service, which allows to safeguard the receipts of expenses for a certain number of years, in an official Vault, recognized by the Tax departments of the State Administration. If set to true, then the bookkeeper is allowed to manage the vault in the name of its client.
enableClientVaultOnNewClient boolean Whether to enable automatically the client Vault when the bookkeeper creates a new organization.
allowSoloPlanClient boolean Jenji offers many commercial plans, among which the SOLO (FREE) plan. This plan is free forever for our users, although it does not include all features of Jenji. If set to true, then the bookkeeper may create clients with a SOLO plan.
mustUseTemplate boolean Is an org must be created with template ? If true, the template is mandatory.

BookkeeperGroup

A group represents a team of the bookkeeper. It includes members of the team (users), and defines security rights.

field type description
id String Unique identifier of the group in Jenji (either "root" for the root group, or a UUID).
name String The name of the team. In the case of a bookkeeper with only the default root group, this is the same as the company name.
parentGroupId String Groups can be articulated together as a hierarchy. The parent group identifier references the parent group of this current group. All groups have a parent, except the root group which stands at the top, which has no parent (null).
createdAt OffsetDateTime Timestamp of creation of the group.
updatedAt OffsetDateTime Timestamp of last update of the group.

BookkeeperUser

A user is a team member (e.g. a sales representative, an accountant...) of a bookkeeper group.

field type description
id String Unique identifier of the User in Jenji (UUID or email, depending on the original registration channel).
bookkeeperId String Unique identifier of the bookkeeper to which the user belongs.
groupId String Unique identifier of the group of the bookkeeper to which the user belongs.
internalId String Optional field, containing the internal identifier of the user in the information system of the bookkeeper. This may help when querying the APIs and performing various mapping tasks.
firstName String First name of the user, like "Alex" in "Alex Pence".
lastName String Last name of the user, like "Pence" in "Alex Pence".
updatedAt OffsetDateTime Timestamp of the last update of the user.
createdAt OffsetDateTime Timestamp of the creation of the user.
blockedAt OffsetDateTime Timestamp of the blocking of the user. This field is null when the user is not blocked.

Category

A category is the primary analytic feature of an expense. It may for instance be a "meal" or an "hotel".

The system provides standard categories, but also allows organizations to define and use their own additional categories.

field type description
id String Identifier of the category. This is usually a code unique within the organization, either a standard code for a Jenji category, or a custom code for a custom category.
disabled Boolean The category may be disabled, i.e. is not usable on new expenses. Previous expenses which reference this category may still use it.
notSelectable Boolean The category is still valid, but not usable.
labelsPerLanguage Map<String,String> The labels of the category, per language, as displayed to front clients (web application, mobile applications). Organization which define custom categories are encouraged to define labels for all the languages they manage.
ocrMappedStandardCategories String[] List of standard category codes to map onto the custom category, when our AI-based agent analyzes a receipt and derives a standard category which has been replaced by a custom category by the organization.
order Integer Order of the category for front clients.
parentCategoryId String Categories may be hierarchical; child categories reference a parent category.
iconId String The identifier of the icon used to display the category in front clients.
colorId String The identifier of the color used to display the category in front clients.
scopeCondition ScopeCondition Allow to manage the visibility of the category, using advanced conditions

CompareMode

value description
GT Strictly greater than
GE Greater or equals
LT Strictly lesser than
LE Lesser or equals
EQ Equals

CustomField

Custom fields are analytic fields freely defined by an organization, which may be filled in by a user when creating an expense.

field type description
key String This is the unique code of the custom field.
type String The custom field may only contain values of the same type. Currently supported types include:
  • DATE
  • LONG
  • LIST
  • LONGTEXT
  • NUMBER
  • STRING
  • STRING_SET
  • TIME_HH_MM
  • EXTERNAL
  • PLACE
  • BOOLEAN

New types may be regularly added.

minimumValue BigDecimal Only for custom fields of type NUMBER or LONG. The minimum value allowed for this custom field.
maximumValue BigDecimal Only for custom fields of type NUMBER or LONG. The maximum value allowed for this custom field.
listId String Only for custom fields of type LIST, generated by the backend. ID required to manipulate the list of options associated with this custom field.
required Boolean Whether the custom field is mandatory when creating an expense.
labelsPerLanguage Map<String,String> Localized labels of the custom fields. Organizations are encouraged to provide labels for each language that they manage.
editableByGroups String[] List of identifiers of organization groups which may use and edit the values of a custom field.
visibleByGroups String[] List of identifiers of organization groups which may use and view (but not edit) the values of a custom field. Groups that may edit a custom field, may also view it.
order Integer Order of the custom field, for front clients.
visibleScopeCondition ScopeCondition Allow to manage the visibility using advanced conditions
configuredByAPI Boolean Whether this custom field may be configured, updated or deleted only by external API calls, and not manually within the app by an organization user. Setting this flag to true is an equivalent of setting the 3 flags {disableConfiguration, disableOptionConfiguration, disableDeletion} to true. This flag takes precedence over the other flags.
disableConfiguration Boolean Disable the button to configure the custom field within the app
disableOptionConfiguration Boolean Disable the button to configure custom field options (for collection types) within the app
disableDeletion Boolean Disable the button to delete the custom field within the app
validation CustomFieldValidation validation defines rules for custom field values.

CustomFieldValidation

Custom fields validation defines rules for custom field values.

field type description
minimumValue BigDecimal Applicable to custom fields of type NUMBER or LONG: minimum allowed value.
maximumValue BigDecimal Applicable to custom fields of type NUMBER or LONG: maximum allowed value.

CustomOption

field type description
id String This is the unique identifier of the custom option.
labelsPerLanguage Map<String,String> Localized labels of the custom option. Organizations are encouraged to provide labels for each language they manage.
extra String A field to hold extra information about the option, it can hold a complete JSON object.
accountingCode String This is a code, used in accounting exports
disabled Boolean The option may be disabled. It acts as a logical deletion, e.g. existing items still reference the option, but new ones cannot.
scope String scope : the option must be seen by a user, a group or user owning custom field. For user, specify user Id. For group, specify group Id. For user custom field, specify user custom field value. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

scopeCondition ScopeCondition scopeCondition : the option must be activate on calculated condition. The setup of the custom field is by made by your project manager. Feel free to question him on these options.

Optional.

DailyUserActivity

Aggregated statistics about actions in Jenji for a user and a day.

field type description
userId String The user identifier. Format: UUID v4.
day String The day of activity. Format: YYYY-MM-DD.
organizationId String The organization identifier. Format: UUID v4.
created int The number of expenses created that day. Increased as soon as the user creates a standard, mileage or allowance expense.
checked int In organizations with the compliance step enabled, incremented as soon as the user marks an expense as 'compliant' or 'not compliant'. For organizations with a custom expense workflow, incremented when the user performs an intermediary validation step.
Only possible for users with expense verification rights or equivalent profiles.
decided int Incremented as soon as the user marks an expense as accepted or rejected. For organizations with a custom expense workflow, incremented when the user performs the final validation step on an expense.
Only possible for users with expense validation rights or equivalent profiles.
accounted int Incremented when an accounting export is marked as 'accounted'. Every expense in the export increments this counter by 1.
Only possible for users with accounting rights.
paid int Incremented when a payroll export is marked as 'reimbursed'. Every expense in the export increments this counter by 1.
Only possible for users with accounting rights.
deleted int Incremented as soon as the user changes the state of an expense to 'DELETED'.
Since Jenji only performs logical deletions, multiple delete/undelete operations on a same expense will increment this counter multiple times.
ignored int The number expense actions that would usually be billed but are ignored because of special organization rules. This field can safely be ignored if no such rules have been contractually defined.

Delegation

A delegation represents the right for a user to act as another user (impersonation), to create or edit expenses for this user, or perform some administrative tasks, such as verifying or validating an expense.

A group delegation represents the right of a user to act on behalf of all users belonging to a referenced group.

field type description
id String The delegation identifier, autogenerated with user id or group id if not present
userId String The identifier of the user on whom the current user is given a delegation.
groupId String The identifier of the group on which the current user is given a delegation. All users of that group may be impersonated.
permission DelegationPermission The permission type granted by the delegation (read-only, write etc).
start LocalDate The date from which the delegation is valid. Only applies to user delegations.
end LocalDate The date after which the delegation ends. Only applies to user delegations.

DelegationPermission

Qualifies which actions a user can do on behalf of a delegated user.

value description
READ The user is granted a read-only access to the delegated user.
WRITE The user is granted all rights on the delegated user, i.e. can perform any action on behalf of the delegated user.
PERSONAL The user is granted restricted rights on the delegated user, namely the ability to view, create and edit expenses only.
NONE The user is granted no right at all.

DistanceUnit

Distance unit.

value description
KM Kilometers
MI miles

Expense

3 variants:

StandardExpense

A standard expense, with a receipt scanned and uploaded to Jenji.

field type description
id String Unique identifier of the expense in Jenji (a UUID).
userId String Unique identifier of the organization user for which the expense applies (either an email or a UUID, depending on the acquisition channel).
organizationId String Unique identifier of the organization to which the expense user belongs. This identifier is determined by the routing rules declared for the organization, and is set right after the expense creation.
time LocalDate Day on which the expense occurred (imputation).
explanation String Explanation for the expense, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
tags String[] Simple labels, freely settable by the user who creates the expense. Tags may be used to search and find expenses easily in the various front clients (web application, mobile applications).
total BigDecimal The total amount of the expense, including taxes.
currency String The currency of the total amount. This currency should match the one specified in the receipt, when there is a receipt available.
country String The country in which the expense occurred.
billable Boolean Whether the expense may be billed to another party.
reimbursable Boolean Whether the expense may be reimbursed to the user who has created it.
attendees String[] The expense may be related to an event to which many users of the organization have attended. In such cases, the list of attendees contain the identifiers or these users.
state String The state the expense is in, when the query is performed. The state may vary across organizations, depending on whether they have defined a custom workflow for expense management.
label String The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...).
customFields Map<String,Object> Custom fields are defined by organizations, to help classify an expense for analytic purposes. This fields maps values for all required custom fields.
reimbursement Reimbursement Contains all the details of the reimbursement of the expense to the user. This field is only set after the expense has been validated.
createdAt OffsetDateTime Timestamp at which the expense was created.
createdWith String Medium through which the expense was created (mobile phone, web service...).
updatedAt OffsetDateTime Timestamp at which the expense was last updated.
validatedBy String Identifier of the user who has validated the expense (standard workflow).
validatedAt OffsetDateTime Timestamp at which the expense was validated (standard workflow).
accountedBy String Identifier of the user who has exported the expense for accounting (standard workflow).
accountedAt OffsetDateTime Timestamp at which the expense was accounted for (standard workflow).
paidBy String Identifier of the user who has authorized the reimbursement of the expense (standard workflow).
paidAt OffsetDateTime Timestamp at which the expense was reimbursed to the user (standard workflow).
checkedBy String Identifier of the user who has checked the expense (standard workflow).
checkedAt OffsetDateTime Timestamp at which the expense was checked (standard workflow).
deletedBy String Identifier of the user who has deleted the expense (standard workflow).
deletedAt OffsetDateTime Timestamp at which the expense was deleted (standard workflow).
warnings ExpenseWarning[] List of the expense warnings (duplicate, invalid receipt...).
category String An expense is attached to a primary category, like "meal" or "hotel". We propose standard categories to begin with, but the organization may freely add custom categories if it so wishes. Categories are declared on the organization itself.
receiptKey String The key of the receipt, obtained when uploading the receipt to the Jenji Storage. Once the receipt has been uploaded, it may not be changed.
invalidReceipt Boolean Whether the receipt was deemed invalid during our processing.
paymentMethodId String The identifier of the payment method which was used to pay the expense (for instance a credit card). Payment methods are declared on the groups of the organization.
totalWithoutTax BigDecimal The total before tax.
totalInMasterCurrency BigDecimal The total expressed in the master currency of the organization (may differ from the currency of the expense). The conversion is made with a standard exchange rate, unless the organization has specified custom conversion policies in its settings.
totalWithoutTaxInMasterCurrency BigDecimal The total without tax, expressed in the master currency of the organization (may differ from the currency of the expense).
totalConversionRate BigDecimal The exchange rate used to convert the amounts from the expense currency to the master currency of the organization.
taxes Tax[] The various taxes applied to the original amount.
type ExpenseType

Mileage

An expense resulting of a travel made by a user, with a personal vehicle.

field type description
id String Unique identifier of the expense in Jenji (a UUID).
userId String Unique identifier of the organization user for which the expense applies (either an email or a UUID, depending on the acquisition channel).
organizationId String Unique identifier of the organization to which the expense user belongs. This identifier is determined by the routing rules declared for the organization, and is set right after the expense creation.
time LocalDate Day on which the expense occurred (imputation).
explanation String Explanation for the expense, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
tags String[] Simple labels, freely settable by the user who creates the expense. Tags may be used to search and find expenses easily in the various front clients (web application, mobile applications).
total BigDecimal The total amount of the expense, including taxes.
currency String The currency of the total amount. This currency should match the one specified in the receipt, when there is a receipt available.
country String The country in which the expense occurred.
billable Boolean Whether the expense may be billed to another party.
reimbursable Boolean Whether the expense may be reimbursed to the user who has created it.
attendees String[] The expense may be related to an event to which many users of the organization have attended. In such cases, the list of attendees contain the identifiers or these users.
state String The state the expense is in, when the query is performed. The state may vary across organizations, depending on whether they have defined a custom workflow for expense management.
label String The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...).
customFields Map<String,Object> Custom fields are defined by organizations, to help classify an expense for analytic purposes. This fields maps values for all required custom fields.
reimbursement Reimbursement Contains all the details of the reimbursement of the expense to the user. This field is only set after the expense has been validated.
createdAt OffsetDateTime Timestamp at which the expense was created.
createdWith String Medium through which the expense was created (mobile phone, web service...).
updatedAt OffsetDateTime Timestamp at which the expense was last updated.
validatedBy String Identifier of the user who has validated the expense (standard workflow).
validatedAt OffsetDateTime Timestamp at which the expense was validated (standard workflow).
accountedBy String Identifier of the user who has exported the expense for accounting (standard workflow).
accountedAt OffsetDateTime Timestamp at which the expense was accounted for (standard workflow).
paidBy String Identifier of the user who has authorized the reimbursement of the expense (standard workflow).
paidAt OffsetDateTime Timestamp at which the expense was reimbursed to the user (standard workflow).
checkedBy String Identifier of the user who has checked the expense (standard workflow).
checkedAt OffsetDateTime Timestamp at which the expense was checked (standard workflow).
deletedBy String Identifier of the user who has deleted the expense (standard workflow).
deletedAt OffsetDateTime Timestamp at which the expense was deleted (standard workflow).
warnings ExpenseWarning[] List of the expense warnings (duplicate, invalid receipt...).
distance BigDecimal The distance travelled by the user, required to compute the amount to reimburse.
computedDistance BigDecimal The distance computed via Google Maps.
distanceUnit DistanceUnit The unit of the distance (km or mi, default is km).
numberOfPassengers Integer The number of passengers transported by the user on his/her trip.
vehicleId String The identifier of the personal vehicle of the user, defined in his/her profile.
waypoints Waypoint[] The waypoints describes the different points of the journey made by the user. Each waypoint may include geographical coordinates, or addresses.
type ExpenseType

Allowance

An allowance is an expense which amount (among other things) is fixed, based on company rules. For instance, one may receive an allowance of 15\u20ac for lunches.

field type description
id String Unique identifier of the expense in Jenji (a UUID).
userId String Unique identifier of the organization user for which the expense applies (either an email or a UUID, depending on the acquisition channel).
organizationId String Unique identifier of the organization to which the expense user belongs. This identifier is determined by the routing rules declared for the organization, and is set right after the expense creation.
time LocalDate Day on which the expense occurred (imputation).
explanation String Explanation for the expense, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
tags String[] Simple labels, freely settable by the user who creates the expense. Tags may be used to search and find expenses easily in the various front clients (web application, mobile applications).
total BigDecimal The total amount of the expense, including taxes.
currency String The currency of the total amount. This currency should match the one specified in the receipt, when there is a receipt available.
country String The country in which the expense occurred.
billable Boolean Whether the expense may be billed to another party.
reimbursable Boolean Whether the expense may be reimbursed to the user who has created it.
attendees String[] The expense may be related to an event to which many users of the organization have attended. In such cases, the list of attendees contain the identifiers or these users.
state String The state the expense is in, when the query is performed. The state may vary across organizations, depending on whether they have defined a custom workflow for expense management.
label String The vendor of the service for which the expense has occurred (e.g. the name of a restaurant, a taxi company...).
customFields Map<String,Object> Custom fields are defined by organizations, to help classify an expense for analytic purposes. This fields maps values for all required custom fields.
reimbursement Reimbursement Contains all the details of the reimbursement of the expense to the user. This field is only set after the expense has been validated.
createdAt OffsetDateTime Timestamp at which the expense was created.
createdWith String Medium through which the expense was created (mobile phone, web service...).
updatedAt OffsetDateTime Timestamp at which the expense was last updated.
validatedBy String Identifier of the user who has validated the expense (standard workflow).
validatedAt OffsetDateTime Timestamp at which the expense was validated (standard workflow).
accountedBy String Identifier of the user who has exported the expense for accounting (standard workflow).
accountedAt OffsetDateTime Timestamp at which the expense was accounted for (standard workflow).
paidBy String Identifier of the user who has authorized the reimbursement of the expense (standard workflow).
paidAt OffsetDateTime Timestamp at which the expense was reimbursed to the user (standard workflow).
checkedBy String Identifier of the user who has checked the expense (standard workflow).
checkedAt OffsetDateTime Timestamp at which the expense was checked (standard workflow).
deletedBy String Identifier of the user who has deleted the expense (standard workflow).
deletedAt OffsetDateTime Timestamp at which the expense was deleted (standard workflow).
warnings ExpenseWarning[] List of the expense warnings (duplicate, invalid receipt...).
category String An expense is attached to a primary category, like "meal" or "hotel". We propose standard categories to begin with, but the organization may freely add custom categories if it so wishes. Categories are declared on the organization itself.
receiptKey String The key of the receipt, obtained when uploading the receipt to the Jenji Storage. Once the receipt has been uploaded, it may not be changed.
invalidReceipt Boolean Whether the receipt was deemed invalid during our processing.
paymentMethodId String The identifier of the payment method which was used to pay the expense (for instance a credit card). Payment methods are declared on the groups of the organization.
totalWithoutTax BigDecimal The total before tax.
totalInMasterCurrency BigDecimal The total expressed in the master currency of the organization (may differ from the currency of the expense). The conversion is made with a standard exchange rate, unless the organization has specified custom conversion policies in its settings.
totalWithoutTaxInMasterCurrency BigDecimal The total without tax, expressed in the master currency of the organization (may differ from the currency of the expense).
totalConversionRate BigDecimal The exchange rate used to convert the amounts from the expense currency to the master currency of the organization.
taxes Tax[] The various taxes applied to the original amount.
templateId String An allowance always references a template, where fixed parts of the expense are defined.
type ExpenseType

ExpenseBaseField

value description
TOTAL Expense total
TOTAL_WOT Expense total without tax
CATEGORY Expense category code
EXPENSE_TYPE Expense type mileage / allowance / per-diem / classic
CURRENCY Expense currency code (EUR, USD, ...)
COUNTRY Expense country code (FR, US, ...)
META_STATE Expense meta-state (Classic states + custom ones)
PAYMENT_METHOD Expense payment method id
ALLOWANCE_ID Allowance template id
BILLABLE Billable flag
ATTENDEES Attendees list (for empty conditions)

ExpenseRequest

field type description
id String Unique identifier of the expense request in Jenji (a UUID).
shortId String Unique short Id identifier
label String Label of expense request
type String Type of expense request
userId String Unique identifier of the organization user for which the expense request applies (either an email or a UUID, depending on the acquisition channel).
state String State of the expense request
comment String Explanation for the expense expense request, provided by the user who has created the expense. This explanation will be read by the manager who approves the expense.
expenses String[] Expenses Id of linked expenses.
creationDate OffsetDateTime Creation date of expense Request.
customFields Map<String,Object> Custom fields are defined by organizations, to help classify an expense request for analytic purposes. This fields maps values for all required custom fields.
files ExpenseRequestFile[] Expense request attached files.

ExpenseRequestFile

field type description
name String Real file name (displayed in UX).
file String File reference in Jenji storage system.

ExpenseType

An expense may be of a certain type, and some fields of an expense depend on the declared type (such as the distance in the case of a mileage expense).

value description
STANDARD Standard expense (code S). Expense with a receipt.
MILEAGE Mileage expense (code M). For travels made with a personal vehicle, with specific company/state policies.
ALLOWANCE Allowance declaration (code A).
PERDIEM Per-Diem allowance declaration (code P).

ExpenseWarning

An expense warning describes a custom rule to be applied to an expense, to check some of its state. For instance, a "duplicate" warning tells when 2 expenses of the same amount are created on the same day.

field type description
warningRuleId String The identifier of the warning rule. Either the identifier of a custom rule (a UUID), or a reserved rule identifier (e.g. "duplicate").
userId String Identifier of the user who own the warning (user of the targeted expense)
time LocalDate Day on which the expense owning the warning occurred.
updatedAt OffsetDateTime Timestamp of the update of the warning.
code String The custom code chosen when creating the warning rule.
labelsPerLanguage Map<String,String> Custom labels for the warning, by language code.

Custom labels are optional, they are only set for warnings generated by certain warning rules. When missing, default labelling algorithms should be applied, e.g. derive appropriate labels from the warning code, or from the default labels of the associated warning rule.

isPreventingValidation Boolean Indicates whether this warning should prevent the validation of the expense/request or not
mutedAt OffsetDateTime Timestamp of the muting of the warning.
mutedBy String Identifier of the user who has muted the warning.
linkedExpensesIds String[] Identifiers of the expenses that are related to the warning.

Organization

An organization is an operating company, for which we want to track expenses. Members of the organization, such as sales representatives, managers, accountants, may gain access to the organization as organization users, to act at the many steps of the workflow of expense management.

field type description
id String Unique identifier of the Organization in Jenji (UUID).
name String Name of the organization, usually the name of the company.
plan String Commercial plan of the organization. One of:
  • FREE: also known as SOLO plan, this is the forever-free plan for Jenji, with restricted features.
  • PRO: standard paying plan, with most features.
  • ENTERPRISE: custom paying plan for enterprises, with custom system integrations.
createdBy String Medium through which the organization was created (backend, mobile application...).
createdAt OffsetDateTime Timestamp of the creation of the organization.
masterCurrency String The reporting currency of the organization. Expenses may be expressed in local currencies, different from the organization currency, but amounts are always converted and reported to the currency of the organization.
masterCountry String The reporting country of the organization.
masterLanguage String The reporting language of the organization.
masterDistanceUnit DistanceUnit Distance unit for the organization. Default is km.
states String[] List of the organization states. From:
  • BLOCKED: Blocks all user of the organization, depending on other states, they might be blocked on the dashboard or the billing page.
  • INVALID_PAYMENT: Displays a message to users to warn them that due payment is invalid.
availableLanguages String[] All languages usable by the organization.
categories Category[] All categories allowed for the organization. May contain standard categories, as well as custom categories, created by the organization.
groups OrganizationGroup[] The hierarchy of groups of the organization (each group represents an operational team of the organization). The top group is named "root group", it is the default group and it may not be deleted.
userCustomFields CustomField[] List of custom fields which values may be customized for each user.
groupCustomFields CustomField[] List of custom fields which values may be customized for each group.
expenseCustomFields CustomField[] List of default custom fields usable in an expense. Other custom fields may be declared on the expense, depending on the logged user and his/her group.
expenseRequestCustomFields CustomField[] List of default custom fields usable in an expense request.
advanceCustomFields CustomField[] List of default custom fields usable in an advance.
vehicleCustomFields CustomField[] List of default custom fields usable in a vehicle.
features Map<String,Boolean> List of technical features currently active for the organization. Features may not be enabled or disabled by API, please contact our Support if you wish to change them.
templateId String ID of the last applied template on the organization.

OrganizationCommunication

Any business message defined by an organization group manager to inform all users of that group. ex: 'Please enter all your expenses before the 25th of the month to be reimbursed'.

field type description
id String Unique identifier of the communication in Jenji (UUID).
code String Code freely defined by a manager to identify a specific communication in a human readable way.
groupId String Identifier of the organization group for which the communication has been defined.
messagesPerLanguage Map<String,String> The messages of the communication, per language, as displayed to front clients (web application, mobile applications).
level String Level of the communication : INFO, WARNING, ERROR, SUCCESS.
startDate OffsetDateTime Start date of the communication. If null, the communication is considered as started.
endDate OffsetDateTime End date of the communication. If null, the communication is considered still running.
updatedAt OffsetDateTime Timestamp of the last modification of the communication.

OrganizationGroup

A group represents a team of the organization. It includes members of the team (users), and defines security rights.

field type description
id String Unique identifier of the group in Jenji (UUID).
internalId String Optional field, an internal id for the team, in the organization information system.
name String The name of the group / team.
parentGroupId String Groups form a hierarchy, topped by a "root group". All groups have a parent group, except the root group.
paymentMethods PaymentMethod[] List of payment methods usable by the users of the group, when they create expenses.
customFieldValues Map<String,?> List of custom field values, by custom field code. The serialized expression for values depends on the type of the custom field.
createdAt OffsetDateTime Timestamp of the creation the group.
updatedAt OffsetDateTime Timestamp of the last update of the group.

PaymentMethod

Payment method used by the organization user to pay for the expense, like a personal credit card.

field type description
id String Unique identifier of the payment method in Jenji (UUID).
label String The label of the payment method, to help the user select the appropriate method when creating the expense.
labelsPerLanguage Map<String,String> The labels of the payment method, per language, as displayed to front clients (web application, mobile applications).
code String The code of the payment method, available in various exports.
reimbursable Boolean Whether any expense made with this payment is reimbursable. A company credit card, for instance, would not incur reimbursable expenses, while a personal credit card would require reimbursements.
dissociated Boolean Whether the payment method is dissociated.
disabled Boolean Whether the payment method is now disabled, i.e. may not be used on new expenses.
transactionProvider String A payment method may be associated with a transaction provider, such as a bank. Jenji offers many integration features with existing banks, whereby an organization may allow Jenji to retrieve bank transactions from its bank, so as to automatically reconcile an expense with a matching bank transaction.

ReceiptDownload

A secure URL from which the receipt of an expense may be downloaded. This URL remains valid for a few minutes only.

field type description
downloadUrl String The url to download the receipt.

ReceiptUpload

A secure URL to where a receipt may be uploaded, as well as a technical key pointing to the location, to be referenced into the expense. This URL remains valid for a few minutes only.

field type description
uploadUrl String The url to upload the receipt.
key String The key to link the receipt and the expense.

Reimbursement

Contains all details of the actual reimbursement of an expense to the organization user.

The amount reimbursed to the user is computed as:

field type description
reimbursementCurrency String The currency of the reimbursed amount and advance imputations. This is usually the master currency of the organization, unless overridden by/for a certain user.
reimbursableAmount BigDecimal This is the amount of the expense which is reimbursable to the user after the organization reimbursement policies have been applied. It is usually the total amount of the expense, unless the organization has defined a maximum reimbursable amount.

For instance, a user may have dinner for 25\u20ac, but the company rules state that only up to 20\u20ac would be reimbursed for dinners. The reimbursable amount thus becomes 20\u20ac, and not 25\u20ac.

advances Advance imputation[] Some advances may be paid to the user before any expense is done. When an expense is reimbursed, the amounts originally paid as advances are subtracted from the reimbursable amount. This field holds the details of the imputations on the advances provisioned to the user.
dueAmount BigDecimal This represents what the company still owes to the user, after advances have been subtracted from the reimbursable amount.

ScopeCondition

Base interface for all scope condition.

All objects must have a type condition with a valid constant. The type defines which class is instantiated and which properties are available. Type naming convention are the class name without the ScopeCondition in upper snake case.

ie: AndScopeCondition -> AND, HasAnyProScopeCondition -> HAS_ANY_PRO

22 variants:

AndScopeCondition

Is true if all condition in conditions attribute are true.

Will return false if conditions list is empty

field type description
conditions ScopeCondition[] Conditions to evaluate

OrScopeCondition

Is true if one condition in conditions attribute is true.

Will return false if conditions list is empty

field type description
conditions ScopeCondition[] Conditions to evaluate

UcfEqScopeCondition

Is true if user custom field is equals to value.

For multi list custom fields, it is true if the list contains value

field type description
code String User custom field code
value String User custom field required value. It is always a String even for number custom fields. For boolean, use true or false.

UcfEmptyScopeCondition

Is true if user custom field is null or empty

field type description
code String User custom field code

UcfNotEmptyScopeCondition

Is true if user custom field is not empty

field type description
code String User custom field code

HasAnyProScopeCondition

Is true if user has at least one of the profiles specified. See your organization configuration for available profiles.

field type description
profiles String[]

IsAdminScopeCondition

Is true if the user is administrator of any group

field type description
isAdmin Boolean null is considered equals to true

IsInGroupScopeCondition

Is true if the user is in one of the group specified

field type description
groups String[]

IsAccountantScopeCondition

Is true if the user is accountant of any group

field type description
isAccountant Boolean null is considered equals to true

IsCheckerScopeCondition

Is true if the user is checker of any group

field type description
isChecker Boolean null is considered equals to true

IsManagerScopeCondition

Is true if the user is manager of any group

field type description
isManager Boolean null is considered equals to true

NotScopeCondition

Is true if condition is false

field type description
condition ScopeCondition

TrueScopeCondition

Is always true

field type description

FalseScopeCondition

Is always false

field type description

EcfEqScopeCondition

Is true if expense custom field is equals to specified value

field type description
code String
value String

EcfCompareScopeCondition

Is true expense custom field is greater/lower (based on selected mode) than the specified value

(Works only on number custom field values)

field type description
code String
value BigDecimal
mode CompareMode

EcfEmptyScopeCondition

Is true is an expense custom field is empty

field type description
code String

EcfNotEmptyScopeCondition

Is true is an expense custom field is filled

field type description
code String

EbfEqScopeCondition

Is true if expense base field is equals to specified value

field type description
field ExpenseBaseField
value String

EbfCompareScopeCondition

Is true expense base field is greater/lower (based on selected mode) than the specified value

(Works only on total and total without tax)

field type description
field ExpenseBaseField
value BigDecimal
mode CompareMode

EbfEmptyScopeCondition

Is true is an expense base field is empty

field type description
field ExpenseBaseField

EbfNotEmptyScopeCondition

Is true is an expense base field is filled

field type description
field ExpenseBaseField

Tax

An expense may be eligible to different taxes.

field type description
baseAmount BigDecimal The base amount eligible to the tax. May be part or all of the total without tax.
rate BigDecimal The tax rate to apply on the eligible amount.
amount BigDecimal The resulting tax amount.

TripDistance

An estimation of the distance travelled for a given trip, with a set of waypoints.

field type description
waypoints Waypoint[] All waypoints of the trip, including the origin and the destination.
distance BigDecimal Computed distance, always expressed in kilometers.

User

An organization user, or simply "user", belongs to a group of the organization. Users work at the different steps of the expense workflow, creating expenses, validating them or authorizing reimbursements.

field type description
id String Unique identifier of the User in Jenji (UUID or email, depending on the acquisition channel).
login String Login used by the user to authenticate to Jenji.
email String Email address at which the user may be contacted, to receive technical notifications.
firstName String First name of the user, like "Alex" in "Alex Pence".
lastName String Last name of the user, like "Pence" in "Alex Pence".
organizationId String Identifier of the organization to which the user belongs.
groupId String Identifier of the organization group to which the user belongs.
internalId String Identifier of the user in the information system of the organization.
customFields Map<String,Object> Custom fields available specifically for this user, mapped by their key.
vehicles Vehicle[] List of personal vehicles belonging to the user. These vehicles may be referenced in mileage expenses.
preferredPaymentMethodId String Identifier of the preferred payment method of the user, to be selected by default in graphical interfaces.
preferredCountry String Code of the preferred country of the user, to be selected by default in graphical interfaces.
preferredCurrency String Code of the preferred currency of the user, to be selected by default in graphical interfaces.
preferredDistanceUnit DistanceUnit Code of the preferred distance unit of the user. Allowed values are KM and MI, default is KM.
preferredVehicleId String Identifier of the preferred vehicle of the user, to be selected by default in graphical interfaces.
updatedAt OffsetDateTime Timestamp at which the user was last updated.
createdAt OffsetDateTime Timestamp at which the user was created.
blockedAt OffsetDateTime Timestamp at which the user was blocked. This field is null if the user is not blocked.
profiles UserProfile[] List of profiles associated to the user, allowing him/her to work in the expense workflow.
mainAccount Boolean Boolean indicating whether it is the user main/default account. Default is false, unless it is the only account.
phone String The user phone number.
delegations Delegation[] Delegations granted to the user, either on groups, or on other users.

UserInvitation

Invitation for a user to join an organization. Once the invitation is accepted, the user invitation is used to create the user.

field type description
id String Unique identifier of the User invitation in Jenji (UUID).
login String Login used by the user to authenticate to Jenji.
email String Email address at which the user may be contacted, to receive technical notifications.
firstName String First name of the user, like "Alex" in "Alex Pence".
lastName String Last name of the user, like "Pence" in "Alex Pence".
organizationId String Identifier of the organization to which the user belongs.
groupId String Identifier of the organization group to which the user belongs.
internalId String Identifier of the user in the information system of the organization.
customFields Map<String,Object> Custom fields available specifically for this user, mapped by their key. The definitions of custom fields are set on the root group.
vehicles Vehicle[] List of personal vehicles belonging to the user. These vehicles may be referenced in mileage expenses.
preferredPaymentMethodId String Identifier of the preferred payment method of the user, to be selected by default in graphical interfaces.
preferredCountry String Code of the preferred country of the user, to be selected by default in graphical interfaces.
preferredCurrency String Code of the preferred currency of the user, to be selected by default in graphical interfaces.
state String State of the user invitation. The state can be "WAITING", "ACCEPTED" or "DELETED".
inviteSentAt OffsetDateTime Timestamp at which the user invitation was sent.
createdAt OffsetDateTime Timestamp at which the user invitation was created.
deletedAt OffsetDateTime Timestamp at which the user invitation was deleted. This field is null if the user invitation is not deleted.
profiles UserProfile[] List of profiles associated with the user, allowing him/her to work in the expense workflow.
phone String The user phone number.
delegations Delegation[] Delegations to be granted to the user, either on groups, or on other users.

UserProfile

The management of expenses over time usually follows certain steps, for instance checking the compliance of an expense, accepting or rejecting an expense, and so on. These steps are articulated inside an expense Workflow , which may be either a standard Jenji workflow, or a custom workflow.

A Profile declares a role in that workflow (e.g. a "manager" in charge of accepting expenses), and is associated with rights to perform transitions in the workflow.

Organization users may be assigned profiles for certain organization groups, which allow them to process the expenses according to the workflow in use in the organization.

The profile named admin always exists and gives administrating rights in the organization or on any groups. This profile does not allow to perform any expense transition. Admins of the root group have access to all the organization configuration. Admins of sub-groups can only manage user related configuration for their allowed sub-groups and all sub-groups below.

The profile named accountant always exists and gives accounting rights in the organization or on any groups. This profile allows the creation and management of accounting and payroll exports. If combined with the admin profile, it also allows the edition of the accounting configuration.

field type description
profileId String Mandatory. The identifier of the profile used in the workflow. The organization user will assume this role / profile when processing an expense (e.g. accepting an expense as a manager).
groupIds String[] Mandatory. The list of organization groups for which the user may assume the profile.

Vehicle

A personal vehicle for an organization user. Vehicles are registered to create and estimate mileage expenses, when an organization user travels with his/her personal vehicle, for business.

field type description
id String Unique identifier of the vehicle in Jenji (UUID).
type VehicleType Type of the vehicle, like a car or a motorcycle. Estimation policies for mileage expenses differ depending on the type.
label String The label of the vehicle, to help the user select the right vehicle when creating an expense.
taxHorsepower int Tax horsepower of the vehicle, used to estimate the expense.
engineCapacity Integer The engine capacity in cubic centimeters (cc).
energy VehicleEnergy The energy used in the vehicle (Petrol, Diesel, Electric, LPG).
fixedMileageRate BigDecimal Fixed mileage reimbursement rate, set by the organization, which overrides official tariffs.
fixedMileageRateDistanceUnit DistanceUnit Fixed mileage reimbursement rate distance unit (km or miles)
mileageCalculatorId String The specific mileage calculator to use when computing mileage expenses for this vehicle. When missing, mileage expenses are computed with the default rules applicable for the organization.
disabledAt OffsetDateTime Timestamp at which the vehicle has been disabled. It may not be used in expenses anymore, but remains in the system for history purposes.
checked boolean Whether the registration document has been verified.
customFields Map<String,Object> Custom fields available specifically for this vehicle, mapped by their key.

VehicleEnergy

Energy for a vehicle. Can be used by some mileage calculators to estimate a mileage expense.

value description
ELECTRIC Full electric. Hybrid cars are treated as either petrol or diesel cars for advisory fuel rates.
PETROL
DIESEL
LPG Liquefied Petroleum Gas.

VehicleType

value description
CAR
MOTORCYCLE
MOPED
BIKE

WarningRule

A warning rule defines the conditions on how it should be applied and the labels to be showed to the user.

A single rule can have multiple sub-labels represented as options. For example, you can have a rule to alert of a threshold, and multiple levels of this threshold :

- warning label= Threshold exceeded - option 1: code=m30, label=Meal over 30\u20ac - option 2: code=m60, label=Meal over 60\u20ac - option 3: code=t50, label=Taxi over 50\u20ac

field type description
id String Unique identifier
type WarningRuleType Rule type, for now only EXTERNAL type can be managed by api
labels Map<String,String> Warning main label
options WarningRuleOption[] Warning rule options.
disabled Boolean Disabled rule.
externalRuleId String The external rule ID (optional)

WarningRuleOption

field type description
code String Technical code for this option
labels Map<String,String> Labels for the option
isPreventingValidation Boolean Indicates whether this option should prevent the validation of the expense or not

WarningRuleType

value description
EXTERNAL External rule managed by api (warning manually set on expenses by api instead of Jenji's warning system)

Waypoint

A waypoint is a geographical place, identified either by an address or by coordinates. A travel starts from a waypoint, optionally visits other waypoints, and ends on a waypoint. A simple round-trip travel would start at waypoint A (e.g. an address in Paris), arrive at B (e.g. an address in Lyon), then return back to A.

field type description
address String The address of the way point.
longitude BigDecimal The longitude of the waypoint, if known.
latitude BigDecimal The latitude of the waypoint, if known.