Core concepts and API Overview
This page provides a general overview of interacting with the Journyx REST API and a summary of key concepts and features. See the About REST page for general background information on the REST philosophy and how it applies to the Journyx API, and the differences between REST and the legacy SOAP API.
You can also find the API Reference section here for detailed information on the available endpoints and resources.
REST API interaction summary
Each resource or object in the system has a unique URL (uniform resource locator) in the API. In general, the internal unique ID of the object is part of the URL, so that the URL is unique to that object. For example, a user account might have a URL like this:
https://example.apps.journyx.com/api/v1/users/84A9E688C8AF4931B206F0423C3F70EA
Note that at this time, the REST API is incomplete and several product areas and features are not yet covered. We are working diligently to add new endpoints and improve the developer experience over time.
In addition, collections of resources of the same type can be addressed as a whole, including sorting, filtering, and pagination operations. This is the main way to search in or report on data in the system.
As an example, the collection of all users for the site example
can be found
at this URL:
https://example.apps.journyx.com/api/v1/users
As you can see, the full site name is part of the complete URL for example
and
will vary depending on the site being used, so for now, we will drop the initial
part and just refer to URLs in the API using a server-relative format, such as:
/api/v1/users
Because we are referring to the whole collection (list) of users here, the URL
only has the /users
part. However, we can also refer to a specific user
account by its internal ID:
/api/v1/users/84A9E688C8AF4931B206F0423C3F70EA
In order to find out information about these resources, or change them, we can
send a web (HTTP) request to the server. For example, the GET
method is used
to retrieve a resource (or a collection of them), the POST
method is used to
create a resource, and DELETE
is used to delete a resource, naturally enough.
The tutorial section shows how to directly make
HTTP requests without using a programming language, and also how to use
Python or JavaScript to interact with
the API.
As discussed in the About REST section, "resources" (and collections of them) are the central abstraction of the API and can represent almost anything; typically some kind of object backed by a database or other persistent storage. Other resources can be more virtual or meta in nature, or correspond more to a "command". This documentation will sometimes refer to resources and objects interchangeably.
HTTP Methods
As discussed elsewhere, REST is based on the HTTP protocol.
The methods (verbs) defined by that protocol such as POST
and DELETE
are the
primary actions to work with resources in the Journyx system.
GET
- get (retrieve) a representation of a resource. GETs may also take advantage of various layers of caching, including with conditional GET requests.POST
- Create a new resource. This is the method used to create new objects in the system.PUT
- submit a new version of an existing resource - modify something.- Strictly speaking, in the HTTP standard the submitted version is supposed to
be a complete representation that fully replaces the prior one, but in
practice, many systems, including the JX server, allow incomplete
representations in a
PUT
request. For example, you can submit only the fields that have changed.
- Strictly speaking, in the HTTP standard the submitted version is supposed to
be a complete representation that fully replaces the prior one, but in
practice, many systems, including the JX server, allow incomplete
representations in a
DELETE
- delete a resource.
These methods represent the basic CRUD operations available in most data storage systems; create, read, update, and delete. Of course, your ability to perform any given action will still be limited by your current authorizations (via role abilities and access groups).
There are other methods in HTTP that you may encounter from time to time. The most common are:
HEAD
- likeGET
but only retrieves the headers of the response, without the actual body.PATCH
- used to submit an incomplete representation for modification when a complete one is required byPUT
. ThePATCH
method is not currently used in the Journyx REST API because we accept partial representations onPUT
.OPTIONS
- used to query the server for information about what methods are allowed on a given resource, or what headers are required, etc.
PUT
for partial updatesWhile the PUT
method is supposed to replace the entire resource, in practice
you can use it to update only the fields that have changed (leaving out all
other fields in the request body), also known as a partial update. The HTTP
PATCH
method is designed for partial updates (incomplete representations), but
it is not supported in the Journyx REST API. Instead, PUT
is used for all
updates.
API Overview
This is a summary of the key concepts and features of the Journyx REST API.
-
Resources (objects) such as Users and Projects are addressed by unique URLs, for example:
/api/v1/users/84A9E688C8AF4931B206F0423C3F70EA
-
There are some basic requirements for most API requests:
-
Almost all operations in the API require that the request be authenticated using either:
-
Cookie-based authentication (Recommended)
-
With either authentication method, you can use standard passwords or API Keys. API Keys are especially useful when the site is using Single Sign-On (SSO).
-
-
Certain HTTP request headers are required for
POST
,PUT
, andDELETE
operations:Content-Type
- usuallyapplication/json
- This tells the server what kind of data you are sending.
Accept
- usuallyapplication/json
- This tells the server what kind of response you are expecting.
X-Requested-With
andOrigin
- These must be provided for security reasons (anti-CSRF)
-
Request bodies
- Usually must be in JSON format
- When that is the case, the request
Content-Type
header must be set toapplication/json
- Not all requests require a request body, but most
POST
(create) andPUT
(update) requests do require a JSON body.
-
-
Most API responses have a common structure, such as:
- The Collections PagedResponse schema, which is used for paginated collections of objects.
- An individual ItemResponse schema is used to return a single object.
-
Making
GET
requests to Collections is the main way to find and access resources (objects) such as Users and Projects. A collection is the set of all objects of the given type, and collections support a common set of operations:- Filtering and searching within the collection.
- Sorting (ordering) results
- Pagination or limiting the number of results returned in any single request.
- Selecting which fields are returned
-
The set of objects you can see (referred to in some areas as "viewability") is determined primarily by your Group memberships. If you try to access an object that you do not have permission to see, you will receive a
403 Forbidden
response.- However, for security reasons, we also return
403 Forbidden
for objects that simply do not exist at all, to avoid leaking information about what objects exist in the system.
- However, for security reasons, we also return
-
The set of actions you are authorized to perform, such as creating, modifying, or deleting objects, is primarily determined by your Role abilities, and depending on the resource, may also be influenced by your Group memberships. Trying to perform an unauthorized action will result in a
403 Forbidden
response. Check the documentation for the specific object type to see which abilities might be required.Abilities are granted through rolesAbilities are granted to roles, and roles are assigned to users. If you need to perform an action that you cannot, you may need to have your role(s) adjusted by an administrator.
Administrator authorityOne important thing to know is that even having
Authority - Administrator
is in some cases not sufficient to perform certain actions which may require that additional abilities be granted. One example of this is making use of API Keys. -
Create new objects by
POST
ing to a collection. (Details below)- As mentioned above, all
POST
operations requireX-Requested-With
andOrigin
headers to be provided, along with the appropriateContent-Type
, usuallyapplication/json
.
- As mentioned above, all
-
Modify objects with
PUT
. (Details below)-
Important: All
PUT
modifications require anIf-Match
header to ensure that you are modifying the latest version of the object. The value of theIf-Match
header should be theETag
value of the object you are modifying. The ETag is a response header you receive when youGET
the object. -
In addition, all
PUT
requests require the sameX-Requested-With
andOrigin
security headers asPOST
requests, as well as aContent-Type
for the request body. -
Modifying objects with
PUT
is discussed in more detail below.
-
-
Delete objects with
DELETE
. The object to delete is identified through the URL, which includes the object's unique ID. (Details below)-
The
DELETE
request does not require a request body, and does not return a response body; a successful deletion will return a204 No Content
. -
All
DELETE
requests require the sameX-Requested-With
andOrigin
security headers asPOST
andPUT
requests. TheContent-Type
header is not required forDELETE
requests, because there is no request body.Deleting objects is permanentThere is no way to "undelete" an object once it has been deleted. Be sure you really want to delete an object before you do so.
-
-
Many object types have Custom Fields.
- (TODO: this page is not available yet.)
-
User access to objects is managed through Groups.
- (TODO: this page is not available yet.)
-
You can execute more than one operation in a single request using the batch API.
- This is primarily meant for use cases of creating or updating multiple objects at once, not for reading data from collections.
Collections
Collections are groups of resources of the same type that are accessed with the
GET
method. For example, there are collections for
users, for
projects, entry codes like
Pay Type, and so on.
Collections are one of the most important concepts in the Journyx API because they are the main way you query and access data, and they are discussed in detail on the Collections page. This includes how to select which fields are returned, how to filter (or search) collections, how to sort them, and how to paginate through large collections.
The Collections page has complete details on:
- Filtering and searching within the collection.
- Sorting (ordering) results
- Pagination or limiting the number of results returned in any single request.
- Selecting which fields are returned
Creating objects with POST
To create a new resource (object) in the Journyx system, you use the POST
HTTP
method on the collection endpoint for that resource. This
section outlines the key requirements, headers, permissions, and steps involved
in creating objects using POST
.
The Tutorial page has a section on creating objects with POST.
Basic Requirements for POST
When creating an object with a POST
request, ensure the following:
-
Authentication: You must be authenticated using either cookie-based authentication or HTTP Basic Authentication. Refer to the Authentication documentation for more details.
-
Required Headers: Include the necessary HTTP headers:
Content-Type
: Must be set toapplication/json
to indicate that the request body is in JSON format.Accept
: Should be set toapplication/json
to specify that you expect a JSON response.X-Requested-With
: Set toXMLHttpRequest
for security purposes.Origin
: Set to the base URL of your request (e.g.,https://example.apps.journyx.com
).
infoThe
X-Requested-With
andOrigin
headers are required for security reasons (anti-CSRF measures) and must be provided in allPOST
,PUT
, andDELETE
requests. -
Request Body: The request body must be a JSON object containing the necessary fields for the resource you are creating. Required fields vary depending on the resource type, so refer to the specific endpoint's documentation for details.
-
Permissions and Abilities: You must have the necessary permissions (abilities) to create the resource. Abilities are granted through roles assigned to your user account. Lacking the required abilities will result in a
403 Forbidden
response.Abilities are granted through rolesIf you encounter permission issues, you may need to have your role(s) adjusted by an administrator to include the necessary abilities.
Example: Creating a User
To illustrate the process, let's consider creating a new user in the system.
Required Abilities
Creating a user requires one of the following abilities:
User - Add
ability, orAuthority - Administrator
ability.
Required Headers
Your POST
request must include the following headers:
Content-Type: application/json
Accept: application/json
X-Requested-With: XMLHttpRequest
Origin: https://example.apps.journyx.com
Request Body
The JSON request body must include the required fields for the user object. For creating a user, the minimum required fields are:
user_login
: The username or login identifier for the user.fullname
: The full name of the user.
Note: If your site uses Single Sign-On (SSO), the user_login
field usually
needs to match the user's email address, UPN (User Principal Name), or another
primary identifier used in the external authentication system.
There may be other considerations when creating users or updating users; see those endpoints for full details.
Example Request Body
{
"user_login": "jdoe",
"fullname": "John Doe",
"email": "jdoe@example.com",
"new_pw": "SecurePassword123!",
"new_pw2": "SecurePassword123!",
"expire_new_pw": false
}
Making the Request
POST /api/v1/users
Complete Request Example:
POST /api/v1/users
Host: example.apps.journyx.com
Content-Type: application/json
Accept: application/json
X-Requested-With: XMLHttpRequest
Origin: https://example.apps.journyx.com
Authorization: Basic <base64-encoded-credentials>
{
"user_login": "jdoe",
"fullname": "John Doe",
"email": "jdoe@example.com",
"new_pw": "SecurePassword123!",
"new_pw2": "SecurePassword123!",
"expire_new_pw": false
}
Successful Response
On successful creation, the server will respond with 201 Created
and several
headers, including the Location
header with the URL of the newly created user
resource, such as in the following example:
HTTP/1.1 201 CREATED
Location: https://example.apps.journyx.com/api/v1/users/84A9E688C8AF4931B206F0423C3F70EA
X-Item-Id: 84A9E688C8AF4931B206F0423C3F70EA
X-Item-Table: users
Content-Type: application/json
{
"success": true,
"status": 201,
"location": "/api/v1/users/84A9E688C8AF4931B206F0423C3F70EA"
}
The response body may contain minimal information about the created resource. To
retrieve full details, such as being able to see what default values were used,
make a GET
request to the Location
URL provided in the response headers.
If the request fails, the server will respond with an appropriate HTTP status code and an error message in the response body.
Modifying objects with PUT
To modify an existing resource in the Journyx system, use the PUT
HTTP method
on that resource's specific URL, which usually contains the Unique ID of the
resource. This section outlines the key requirements and steps for updating
objects using PUT
.
The Tutorial page has a section on updating objects with PUT.
Basic requirements for PUT
When modifying an object with a PUT
request, ensure the following:
-
Authentication: You must be authenticated using either cookie-based authentication or HTTP Basic Authentication.
-
Required Headers:
-
If-Match
: Must contain the currentETag
value of the resource. -
Content-Type
: Must be set toapplication/json
-
Accept
: Should be set toapplication/json
-
X-Requested-With
: Set toXMLHttpRequest
-
Origin
: Set to the base URL of your request.Important: theIf-Match
header is requiredThe
If-Match
header is required for allPUT
requests to prevent concurrent modification conflicts. You can obtain theETag
value by first performing aGET
request on the resource. This is discussed in more detail in the section Tutorial#updating objects.
-
-
Request Body: Include only the fields you want to modify. Unlike some REST APIs, the Journyx API allows partial updates, so you don't need to include unchanged fields.
However, certain required fields are an exception to this in many endpoints.
These are noted in the endpoint documentation. These required fields must always
be present for both POST
(create) and PUT
(update). Relatively few fields
are marked as required, but one example is the
Create users endpoint, where the
user_login
and fullname
field are required in all PUT
updates.
Example: Updating a User
Here's an example of updating a user's fullname
address:
PUT https://example.apps.journyx.com/api/v1/users/84A9E688C8AF4931B206F0423C3F70EA
Host: example.apps.journyx.com
Content-Type: application/json
Accept: application/json
X-Requested-With: XMLHttpRequest
Origin: https://example.apps.journyx.com
If-Match: 1234567890
{
"fullname": "John Q. Doe"
}
email
fieldThe email
field in the Users schema is
currently read-only; to update a user's email address, you must set the
users_attribs:users_email
field instead.
Successful PUT
Response
A successful PUT
update returns a 204 No Content
response with no response
body, but the Location
header has the URL of the updated resource, as shown
here. You can then GET
the resource to verify the changes and obtain the new
ETag
value for subsequent modifications.
HTTP/1.1 204 NO CONTENT
Date: Tue, 29 Oct 2024 17:44:15 GMT
Location: /api/v1/users/C21FBB4E857245DABA8A7E7657CF2FD3
Common Issues with PUT
-
Missing
If-Match
Header: Results in a428 Precondition Required
error -
Stale
ETag
: If another modification occurred since you retrieved theETag
, you'll receive a412 Precondition Failed
error. -
Invalid Fields: Attempting to modify read-only fields or providing invalid values results in a
400 Bad Request
.
After a successful update, perform a GET
request on the resource to verify the
changes and obtain the new ETag
value for subsequent modifications.
Deleting objects with DELETE
To delete an existing resource from the Journyx system, use the DELETE
HTTP
method on that resource's specific URL. Deletion is a straightforward operation
but requires careful consideration as it is permanent.
The Tutorial page has a section on deleting objects.
Basic Requirements for DELETE
When deleting an object with a DELETE
request, ensure the following:
-
Authentication: You must be authenticated using either cookie-based authentication or HTTP Basic Authentication.
-
Required Headers:
X-Requested-With
: Set toXMLHttpRequest
Origin
: Set to the base URL of your request
infoUnlike
POST
andPUT
requests,DELETE
requests don't require theContent-Type
header since there is no request body. -
Permissions: You must have the appropriate deletion ability for the resource type. For example, deleting a user requires either the
User - Delete
ability orAuthority - Administrator
.
Example: Deleting a User
Here's an example of deleting a user:
DELETE /api/v1/users/84A9E688C8AF4931B206F0423C3F70EA
X-Requested-With: XMLHttpRequest
Origin: https://example.apps.journyx.com
Successful DELETE
Response
A successful deletion returns a 204 No Content
response with no response body:
HTTP/1.1 204 NO CONTENT
Date: Tue, 29 Oct 2024 17:44:15 GMT
Deleting objects is permanent and cannot be undone. Always ensure you have selected the correct object before proceeding with deletion.
Other considerations
-
Response Structure: When creating or updating objects, the API may not return the full object in the response body. Use the
Location
header to retrieve the full object if needed. -
Idempotency: Repeated
POST
requests may create multiple resources. Ensure your client application handles this appropriately. -
Error Handling: Always check the response status code and handle errors appropriately in your client application. Use the
error.code
anderror.message
in the response body to determine the cause of the error. -
Data Validation: Ensure that all required fields are included and that data types match the expected formats. Missing or incorrect data will result in a
400 Bad Request
error. -
Permissions: Confirm that your user account has the necessary abilities to perform the operation, for example, creating objects. If you lack the required permissions, you will receive a
403 Forbidden
response. -
Authentication: Make sure you are properly authenticated. An unauthenticated request will result in a
401 Unauthorized
response. -
Security Headers: Do not omit the
X-Requested-With
andOrigin
headers, as they are required for security purposes and to prevent Cross-Site Request Forgery (CSRF) attacks. -
Single Sign-On: If your site uses Single Sign-On (SSO), you may need to use API Keys to make API calls. It is also possible to enable certain accounts to sign in with both the internal password authentication and still use SSO on the web.
-
Custom Fields: Refer to the resource's endpoint documentation for details about working with (admin-defined) Custom Fields that may be associated with that object type.
-
Batch changes: You can execute more than one operation in a single request using the batch API. This is primarily meant for creating or updating multiple objects at once, though modifying objects is still subject to the requirement for the
If-Match
header withEtag
.
Error responses
When the system rejects a request - whether due to insufficient permissions,
inability to perform the action, a malformed request, or another issue — a
human-readable error message is usually returned in the response. In most cases,
this message is accompanied by a fixed code string, such
as NotFoundOrNotAuthorized
, which indicates the general category of the error
within the HTTP response type, such as 400 Bad Request
.
As an API client programmer, the most important thing to look at with each response is the HTTP response code and check for any errors (non-2xx responses).
400 Bad Request
The most typical error response will be 400 Bad Request
, which indicates that
the request was malformed or unusable in some way. The response body will
contain more detailed error code and a human-readable
error message according to the error response schema.
Other error responses
In addition to 400 Bad Request
, there are other common 4xx error responses
such as:
-
401 Unauthorized
- typically means that the credentials provided were incorrect. -
403 Forbidden
- indicates that you do not have permission to access the object or perform the action. However, this is also used for objects that do not exist at all, to avoid leaking information about what objects exist.
Success responses
Typically, a Collection will always respond with a 200 OK
to a GET
request, or 201 Created
if POST
ing (creating) a new object.
The PUT
(update) and DELETE
methods typically respond with 204 No Content
on success.
Error schema
All method types and endpoints will give a non-2xx response, either a 4xx or 5xx
response, if there is a problem. The response body (the
ErrorResponse
schema) will contain
details about the problem.
The error
key will be an object with two sub-keys:
-
code
, which is the fixed error class code mentioned above, such asNotFoundOrNotAuthorized
orValueError
. -
message
- a human-readable error string, which might typically be displayed to an end-user.
In addition, the standard
ErrorResponse
schema can also contain
an errors
array which typically just has the same info as error.message
, but
in some cases might contain additional errors if there were more than one.
There will also be a success
flag, which will be false
in the case of any
error response.
Most errors will be in the 4xx class, such as 400 Bad Request
,
401 Unauthorized
, 403 Forbidden
, etc. The 5xx class of errors is used for
the following cases:
-
500 Internal Server Error
- a generic error that indicates something went wrong on the server side. Although this typically represents an internal programming error, in some cases these errors can be triggered by incorrect or malformed requests and would be resolved if the request were corrected. -
503 Service Unavailable
- indicates that the server is currently unavailable, typically due to maintenance or other temporary issues.
Fixed error codes
This is a partial list of some of the error codes you might encounter. The purpose of these codes is to help group related errors into categories, if this helps you to handle them in your client code.
-
AuthenticationFailed
- typically means that the credentials provided were incorrect. -
InternalError
- indicates a server-side error; although this typically is an internal programming bug, in some cases these can be triggered by incorrect or malformed requests. -
NotFoundOrNotAuthorized
- indicates that the object you are trying to access does not exist, or you do not have permission to access it. -
ValueError
- indicates that some field or bit of data in the request body was malformed or incorrect in some way. -
AlreadyExists
- indicates that the object you are trying to create already exists and cannot be duplicated. -
IntegrityError
- indicates that the request would violate some kind of integrity constraint, such as a foreign key constraint.
Example error response body
This shows an example of a 400 Bad Request
response when a required field is
missing from the request body:
{
"success": false,
"status": 400,
"error": {
"code": "ValueError",
"message": "The 'user_login' field is required."
}
}