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/

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.

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.

  • /start_date/2018-01-01/
  • /end_date/2018-12-31/
  • /start_date/2015-01-01/end_date/2015-12-31/


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


JSON requests return basic id and URL information when as a list request and the complete record values for individual items. As such, using JSON has the most robust response within the LiveWhale API. All of the above RSS and iCal parameters work with JSON and in addition, you may also utilize the following parameters:

  • /start_date/[YYYY-MM-DD]/
  • /end_date/[YYYY-MM-DD]/
  • /only_today/[true or false]/
  • /require_image/[true or false]/


  • /start_date/2013-05-03/ Collect items beginning on this date.
  • /start_date/2013-05-03%2012:00am%20America%5CLos_Angeles/ Shift a start date to a different timezone.
  • /end_date/2013-05-04%2011:59pm%20America%5CLos_Angeles/ Shift an end date to a different timezone.
  • /only_today/true/ Only include items from today, as reflected in the group’s or server’s timezone.
  • /require_image/true/ Require that all content returned possess at least one image.

Paginating JSON results

If you’re querying an especially large results set, you’ll improve performance by paginating the results. In LiveWhale 1.7+, you can specify your pagination arg (/paginate/30 or however many results per page you’d like) and use ?page=1, ?page=2, etc. to fetch subsequent pages of results.

Please note that the endpoint response is modified when pagination is turned on in order to deliver metadata about pagination:

"total_results": 594,
"per_page": 30,
"page": 1,
"total_pages": 20,
"results": [...]

Event Summary / Description

For performance reasons, we don’t include the full description in API results for multiple events. Rather, the summary field is returned as “description.” The intention is to provide an overall list of events, and that users will click into an individual event to read its complete details.

If you want the full details of an event including description, the recommended behavior is to query individual events using a URL like:


Alternatively, some schools use a custom module to load the description and include it in the JSON list results behind a flag, like this:


It requires being a bit careful, as “heavy” queries like that could cause server/database lag depending on the application you’re developing. Those interested in exploring this solution should reach out to support.

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);

$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.