LiveWhale has two main types of API interactions:

(1) a REST API for extracting information from the CMS. This part of the LiveWhale API is closely aligned with LiveWhale Widgets. This means that:

  • in most cases, you can use the content selection and ordering arguments shown in the widget editor (for the matching content type) in a REST URL request;
  • the API respects content visibility, so only live content that is after a scheduled for date and before an archive date; and,
  • since the content could appear on your website, no authentication/authorization is required.

and (2) a content API that allows you to interact directly with the LiveWhale database using simple PHP functions like create(), update(), and delete().


To obtain lists of items from your LiveWhale, make a request to the API via a REST URL. Use the following format:

e.g., http://your.website.edu/live/ical/events/tag/soccer/only_starred/true/

To access an individual content item, use the following format:

e.g., http://your.website.edu/live/profiles/123@JSON


Almost all LiveWhale instances use the default /live/ API path, but you can configure an alternate path if /live/ is unavailable.

[format or @FORMAT]

The format represents the format in which you wish the content returned. Available formats are:

  • /rss/
  • /ical/
  • /json/
  • /csv/ (LiveWhale 2.0+)

When appended to an individual item request, valid values are:

  • @JSON
  • @XML


The content type represents the LiveWhale content you wish returned. Available types are:

  • /pages/
  • /news/
  • /events/
  • /galleries/
  • /forms/
  • /blurbs/
  • /profiles/
  • /images/
  • /files/
  • /places/


The parameters refine the content, ordering and range. In general, almost any argument/value pair you might use as a widget argument will work with the REST API. Here are some helpful formats to remember:

  • They are always paired and there is always a terminal slash.
  • Where a string is used, it should be URL encoded, e.g. /group/LiveWhale%20Staff/.
  • Booleans appear as strings, e.g. /true/ or /false/.
  • Not all parameters work with all formats or with all content types, as they may not apply. (For example, only events have categories.)


This is the integer id of the content item desired.

Hidden Content

By default, all API results only show Live content. However, when developing it may be useful to query for hidden content in certain cases. In LiveWhale 2.0+, adding ?include_hidden=1 to the end of your API request will include hidden results if you are logged-in to LiveWhale (or using an authentication token).


Learn more about the LiveWhale JSON API.


In LiveWhale 2.0+, you can easily export your content in CSV format using /live/csv. This endpoint follows the same general rules as other LiveWhale REST API endpoints, with the exception that it automatically disables all pagination and returns results in a single CSV instead.

  • /live/csv/events/ – a CSV of all events
  • /live/csv/events/group/Student Affairs/ – a CSV of all events from “Student Affairs”
  • /live/csv/news/ – a CSV of all news
  • /live/csv/news/tag/my-tag/ – a CSV of all news stories taggged “my-tag”

Tip: Consider building your query first using /live/json/, and then, when you’ve confirmed that you’re requesting the right set of results, swap in /csv/ for /json/.

Note: If your configuration has JSON API v2 as the site-wide default, your CSV results will also be optimized to only show the basic fields unless you request additional fields. As an example /live/csv/events/response_fields/summary will include the event summary in your CSV.

RSS and iCal

The RSS and iCal formats assume various characteristics from their formats. For example, RSS is automatically limited to 15 items and listed in reverse-chronological order. You can use any of the following parameters in a RSS or iCal request.


You may use and repeat include or exclude group parameters as often as necessary to construct the desired output. All group parameter repetitions are considered as OR. The groups of “me” and “Public” will not result in returned content due to their special status.

  • /group/[group name]/
  • /exclude_group/[group name]/


Like group parameters, tags inclusions and exclusions may be repeated as often as desired. However, because items may be tagged with multiple tags all matching defaults to an AND relationship unless you add the /tag_mode/any/ parameter to force an OR relationship.

  • /tag/[tag name]/
  • /tag/[tag_name]/tag/[tag_name]/
  • /exclude_tag/[tag name]/
  • /tag_mode/any/


For events only, category inclusions and exclusions and matching relationships behave identical to tags above.

  • /category/[category name]/
  • /category/[category_name]/category/[category_name]/
  • /exclude_category/[category name]/
  • /category_mode/any/

You may execute full-text searches with the terms provided.

  • /search/[term or terms]/


By default, event feeds only show upcoming events. You can change this by adding start or end dates. You can also use PHP-readable date strings like today, -24 hours, or next Sunday.

  • /start_date/2022-01-01/
  • /end_date/2022-12-31/
  • /start_date/2015-01-01/end_date/2015-12-31/
  • /start_date/-12 months/
  • /start_date/last Monday/end_date/this Sunday/

More about start_date and end_date formatting.


You may use LiveWhale Places to gather content that has been geo-located. Location combinations typically only require a location (has_location) or relate the content returned to a specific location and radius (near_location and near_distance used together).

  • /has_location/[true or false]/
  • /near_location/[LiveWhale Place id]/
  • /near_distance/[miles distance in decimal]/


Finally, you may use the following two parameters to limit the returned content by quantity or starred status.

  • /max/[integer]/
  • /only_starred/[true or false]/


  • /tag/rock/ Only include items tagged “rock.”
  • /tag/roll/ Only include items tagged “roll.”
  • /tag/rock/tag/roll/ Only include items tagged “rock” and also tagged “roll,” e.g. an AND relationship.
  • /tag/rock/tag/roll/tag_mode/any/ Only include items tagged “rock” or “roll,” e.g. an OR relationship.
  • /category/Performances/ Only include events categorized as a Performance.
  • /category/Performances/category/Important%20Dates/ Only include events categorized as a Performance AND as an Important Date.
  • /category/Performances/category/Important%20Dates/category_mode/any/ Only include events categorized as a Performance OR as an Important Date.

Frequently Asked Questions:

Q. How do I obtain Places (location and location name) from the RSS feed?
A. The location of an item is stored in georss:point and georss:featureName

<georss:point>39.953949 -75.192293</georss:point>
<georss:featureName>Faculty Lounge</georss:featureName>

Q. How do I get the start time of an event in an RSS Feed?
A. The start time is located in of the feed. The datetime is in UTC format allowing for the timezone to be determined by your system.

<pubDate>Wed, 01 Apr 2015 20:30:00 +0000</pubDate>
The date above returns the following time based on my timezone (EST): 04/01/15 4:30pm

Customizing the RSS Format

You may already be customizing the output syntax of your RSS feeds using a custom module or in a project with support. However, since LiveWhale 2.12, you can do this more easily using a special widget template.

To customize the format, copy /public_html/livewhale/templates/widgets/events.rss_default.xml to /public_html/_ingredients/templates/widgets/events.rss_default.xml.

Inside of the _ingredients/ copy, you can see and customize the individual item formatting like you would any events widget:

<arg id="format">
<enclosure url="{image_src}" type="image/jpeg"/>

This same pattern of /_ingredients/templates/widgets/{type}.rss_default.xml also works for other modules, so a LiveWhale CMS developer may want to experiment with modeling a news.rss_default.xml on the events one, if you have external applications that are looking for a specific RSS syntax. Feel free to reach out to support if you run into any questions when editing your rss_default.xml template.

Images API

When you upload images to LiveWhale, we always recommend that you upload the largest available. LiveWhale then makes a reference copy at 3,200 pixels in the largest direction, from which all subsequent images (such as thumbnails) are made.

When an smaller image is made, LiveWhale caches up to 30 of the most recent (keeping track of different sizes and cropping) so that they need not be re-generated with each request. Since LiveWhale 1.5.1, the API now tracks how long it has been since an image has been requested and prune unused images.

REST API URL Structure

Naturally, all images must be publicly available, but the API is also available so that you can generate your own editions of any image. To request an image, certain information is required, but you can derive it from any existing image, such as a thumbnail URL you have from a JSON response, or an image URL in any LiveWhale-powered webpage. One such example URL is:


This API does not offer a lot of options, but there are some pretty choice ones; here’s the breakout of the URL structure, in the order that they should be used:

Option Description
/live/image This is the image API path; it is required.
/gid/### This is the group owning the image by group id (gid); it is required.
/width/### This is the width to scale/crop the image to and is optional even if you request height.
/height/### This is the height to scale/crop the image to and is optional even if you request width.
/crop/1 Specify 1 to crop the image or leave this element out of the request. It is essentially optional but required if you supply both width and height and want to ensure that the image returned is exactly the requested size.
/src_region/x1,y1,x2,y2 If cropping, you can supply the pixel region of the original to crop to; this is optional even if cropping has been requested. x1,y1 is the top-left corner; x2,y2 is bottom-right corner.
/###_filename.jpg This is the id and uploaded filename which together comprise the filename of the master image that LiveWhale made at the time of the upload; it is required.

Additional Considerations

  • If you only request the required elements noted above for any image, you will receive the LiveWhale master image at size.
  • LiveWhale will not upscale images but a few pixels; if you request an image at a width of 500 pixels and the uploaded original is 450 pixels, then you will get only 450 pixels of width in the image returned. In such cases, if height and crop are also requested and the image is taller than the requested height, it will still be cropped for height.
  1. https://my.domain.edu/live/json/galleries/group/News
    The above request finds a list of galleries. It doesn’t include the photos in each gallery in order to keep the response small and quick. Once you find the specific gallery you want, you can perform a second request to get details about that gallery (see below)
  2. https://my.domain.edu/live/galleries/253@JSON
    This request fetches gallery id 253 in JSON format. The resulting response contains a “photos” element, containing all the images in the gallery. Each entry contains an url to the full sized image, the thumbnail, and the text of the caption.

Authenticated Requests

When making requests to LiveWhale’s REST/RSS/JSON API, you are retrieving data anonymously. However, you can perform an authenticated request to:

  • access data that would normally be filtered out of an anonymous request.
  • use the content API (create/update/delete) via REST URL

Step 1: Obtaining your token

In order to perform an authenticated API request, you must first request an access token. Access tokens are reset hourly. Upon receiving a token, your application will also receive an expiration time (of up to an hour). If your application stores the token to perform multiple requests, it must also store this expiration time and fetch a new token upon reaching the expiration time or else it will have further requests denied.

You can obtain an access token that either:

  1. authenticates your request as a particular LiveWhale user (not supported on SSO installations)
  2. authenticates your request, but does not identify with any LiveWhale user

For a user-authenticated token
To request an access token that authenticates your request as a particular LiveWhale user, perform a POST request to https://yourhost/live/auth with POST data:

  1. “username”: your LiveWhale username
  2. “password”: the password for this username

Note: If your installation is set to enable secure logins (most customers) then the “https” is required. This POST request will not work on your install unless you do not require secure logins.

Note: If you are using PHP inside a custom module, you can still obtain an authentication token for a user even if you’re using SSO, with $token = $_LW->getAuthToken($user_id);

For a non-user-authenticated token
To request a token that allows an authenticated request, but does not masquerade as a particular logged-in LiveWhale user, follow the same instructions as above, but with POST data:

  1. “username”: the FTP username OR database username for this LiveWhale installation
  2. “password”: the password associated with the above login, after double-hashing with MD5

With either method (user or non-user token requests), the response will be one of:

  1. {"error":"An explanatory error."}
  2. {"token":"xxxxxxxxxx","expires":"2014-10-06 20:20:18 UTC","expires_ts":1412626818,"expires_remaining":3600}

Step 2: Performing an authenticated request

Once you’ve obtained a user token (xxxxxxxxxx) you can simply add a GET variable to any LiveWhale API request to obtain an authenticated response:


You may expect the usual API response back, but potentially with content impacted by the result of authentication.

Additional requests may be performed with the lw_auth variable, until the token’s expiration time is met. At this point, a new token must be obtained by repeating step 1 above.

Content API

Since LiveWhale 1.6.0, the LiveWhale API allows you to interact with the LiveWhale database using simple PHP or REST functions, and frees you from having to write SQL code or worry about writing directly to the various tables of the database.

For example, to add an event to LiveWhale, you can just use a simple $_LW->create('events') PHP function, and behind-the-scenes LiveWhale will write the necessary data to a number of tables (livewhale_events, livewhale_events_categories, livewhale_events_categories2any, livewhale_tags, etc.). In the past, you may have used custom SQL scripts to do those tasks manually, but the API is here to help you accomplish your goals in a simpler and more future-proof way.

Setting up your script

PHP: Your script must have access to the global $_LW variable in order to perform database operations.
Depending on what kind of script you’re writing, here are a couple recommended workflows:

  1. For admin operations (i.e., a bulk import or other one-time data operations), use a script like the following: Example Private Script.
  2. For user operations (i.e., a special form that creates objects in your database, or other often-repeated actions) use a custom module like the following: Example Custom Module.

REST: The format for a REST API action is https://yourhost/live/ACTION/TYPE/ID, where action is create/update/delete, type is the content type, and ID is the content ID for updating/deleting. For example:

  • Creating an event
    supplying in the POST an array called “data” ($_POST['data']) everything that would normally be in the $data_to_save array.
  • Updating an event (id = 123)
    supplying in the POST an array called “data” ($_POST['data']) everything that would normally be in the $data_to_save array.
  • Deleting an event (id = 123)

The REST API will return the ‘id’ of the created/edited/deleted item on success, or an ‘error’ message on error.

Adding data to LiveWhale with create()

Once you have the information you want to write (from a CSV you’ve imported, a form submission, or elsewhere) you can use the create() function to add it to LiveWhale.

Basic PHP syntax:

if ($id=$_LW->create($data_type, $data_to_save, $as_user)) {
    echo 'Created object '.$id.'<br/>';
} else {
    echo $_LW->error.'<br/>';

$data_type is a string that specifies what you’re creating. It usually matches a module name: blurbs, events, profiles, groups, users. Or it may be a taxonomy, like events_category. Note that associating an image with an event, say, can be done all-in-one and doesn’t require a separate create() to make the image (see example below).

$data_to_save is an array of information to be saved. It may include:

Name Value Type
gid The ID of the group where the content should be created (integer) all
title The name of the content (string) all
status The live/hidden status (integer, 1 = Live, 2 = Hidden) all
visibility The privacy/visibility setting (1 = Everyone, 2 = This group only, 3 = Any logged-in user, 4 = Only with link) all
is_starred Set to 1 to star the content all
is_shared Set to 1 to share the content all
is_archived Set to 1 to archive the content all
associated_data An array of attached tags, categories, and images (see example below) all
summary Summary of the event events
description Description of the event events
date Start date events
date2 End date (optional) events
date_time Start time (leave blank for all day) events
date2_time End time (optional) events
is_all_day Set to 1 for an all day event events
timezone The timezone of the event in PHP format (e.g., ‘America/New_York’) events
categories An array of category (event type) IDs events
repeats Repeating events: How often (1 = daily, 2 = weekly, 3 = monthly, 4 = M-F, 5 = MWF, 6 = TuTh, 7=yearly) events
repeats_from Repeating events: start date for repeating events events
repeats_until Repeating events: end date for repeating events events
repeats_every Repeating events: repeat every X unit (unit set in repeats argument). e.g., set repeats=2 and repeats_every=3 to repeat every three weeks. events
repeats_on Repeating events: array of integers reflecting days of the week on which event should repeat (1 = Sun, 2 = Mon, 3 = Tues, etc.) events
repeats_by Repeating events: 1=repeat by day of the month, 2=repeat by day of the week events
repeats_occurrences Repeating events: end after X number of occurrences events
tid The blurb or profile type being created blurbs, profiles
body The body content of the blurb blurbs
custom_123 A custom field (with ID 123) for a profile type profiles
fullname The name of the group groups
fullname_public The public name of the group groups
firstname The user’s first name users
lastname The user’s last name users
username The user’s or profile owner’s LiveWhale username users, profiles
password The user’s password (only if not using single-sign-on) users
email The user’s email address users
use_email Set to 1 to send notifications to the user’s email address users

(This list is incomplete; your array may include almost any column from the database for that data type. When in doubt, run a test case to create a single object and see if it works as intended or gives an error.)

Note: When creating a repeating event, all repeats_X fields must have values (even if just to “null”) when one of them is set.

$as_user is an integer that specifies the ID of the LiveWhale user who should be indicated as having created the content. If the create() call is executed by a non-logged-in LiveWhale user, the CMS itself will be the creator. Otherwise, the currently-logged-in user will be assumed as the creator, if a user ID is not specified. If creating content in a different group, the currently-logged-in user must have access to that group, or else you should specify a user belonging to that group.

Here is an example of using create() to add an event to LiveWhale. Note the use of the ‘associated_data’ array for attaching tags and an image to the event, and that after the event is created we use its ID to index it for search.

Removing data from LiveWhale with delete()

You can delete data from LiveWhale using the following syntax:

$_LW->delete($data_type, $id, $add_to_trash, $as_user);

$data_type is a string that specifies what you’re deleting. It usually matches a module name: blurbs, events, profiles, groups, users. Or it may be a taxonomy, like events_category.

$id is an integer, the ID of what you’re deleting.

$add_to_trash is a boolean (defaults to true) that adds your deleted object to the trash when set to true, if the module supports it. This argument is optional.

$as_user is an integer that specifies the ID of the LiveWhale user who should be indicated as having removed the content. This argument is optional, however, if delete() is called by a non-logged-in user, you must specify an $as_user who has access to that content (i.e., either an admin or a user from that group).

Updating data in LiveWhale with update()

You can update content in LiveWhale using the following syntax:

$_LW->update($data_type, $id, $data_to_save, $as_user);

$data_type is a string that specifies what you’re updating. It usually matches a module name: blurbs, events, profiles, groups, users. Or it may be a taxonomy, like events_category.

$id is an integer, the ID of what you’re updating.

$data_to_save is an array of the values you’re writing (or overwriting) to the content in question. It follows the same syntax here as in the create() function.

$as_user is an integer that specifies the ID of the LiveWhale user who should be indicated as having updated the content. This argument is optional, however, if update() is called by a non-logged-in user, you must specify an $as_user who has access to that content (i.e., either an admin or a user from that group).

Reading data from LiveWhale with read()

You can read content from LiveWhale using the following syntax:

$_LW->read($data_type, $args, $token);

$data_type is a string that specifies what you’re updating. It usually matches a module name: blurbs, events, profiles, groups, users. Or it may be a taxonomy, like events_category.

$args is an array of your search arguments (optional). Think of them like widget arguments, or arguments you would plug into the REST API. In fact, the read() functionality functions somewhat as a PHP wrapper on the existing JSON endpoint.

$token is an optional authentication token. You might want this to get access to read hidden content, or content with certain permissions. (LiveWhale 2.0+)

Validating create/update requests in LiveWhale with validate()

Since LiveWhale 2.9.0, you can dry-run your create()/update() requests with validate() to return errors before saving.

Note: when validating a create() action, use false for the $id.

if ($_LW->validate($data_type, $id, $data_to_save)) {
echo 'Your $data_to_save is valid.';
} else {
echo 'There was an error with your $data_to_save: ' . $_LW->error;