Shop Forum More Submit  Join Login
COGS #2 by Z-GrimV
After many months of development we are excited to release the all new DeviantArt API. This release includes all the endpoints used in our new mobile apps, adding over 40 new endpoints for your programming pleasure. We hope you enjoy these new features and look forward to seeing the wonderful new things you create.

What's Included?

  • Browse - Access the main browse modes, including More Like This and Journals written by deviants
  • Comments - Access and post user comments
  • Collections - Access collections (favorites)
  • Galleries - Access galleries
  • Feeds - Access various feeds
  • Profiles - Access and manage profile data
  • Friends - Access and manage friends
  • Statuses - Access and post statuses
  • Curated Content - Access our editorial content

Getting Started

You can jump right in by visiting the developer documentation area. Additionally, you will want to read the updated authentication, errors, versioning, and pagination documentation.

Want to try it out right now? You can using the developer console.

Coming Soon

We will be releasing further updates to the API over time. Currently, Message Center and Notes endpoints are omitted. There are plans to include these but they will be released in line with our mobile app releases and after we have reviewed current messaging systems.

Bugs & Feedback

There are many new endpoints so if you find any bugs, we have setup a Github project to report any bugs and feedback can be given in the comments section of this article.

Header artwork: COGS #2 by Z-GrimV

API Updates

Thu May 8, 2014, 10:52 AM
We are pleased to announce the release of a new API backend framework and documentation to support future growth of the deviantART & API's.

New Docs2 by muteor

Endpoint2 by muteor

Whats Changed?

We have been busy over the past few months creating a new framework that will allow us to make changes to the API faster.

The main new features are:
  • Versioning - We now support versioning of endpoints meaning we can make backwards incompatible changes.
  • Error Responses - We have standardized our error responses to make it easier for you to handle errors.
  • Request Specifications - We now have fine grained endpoint parameter specifications that improve request validation greatly.
  • Response Specifications - Responses are now predefined so your client will always receive consistent responses and types from the API.
  • Automated Documentation - All of the above means we can auto-generate documentation so that it doesn't become out of sync when we make changes.


The ability to version changes to the API is one of the more important new features as it means we can now make backward incompatible changes without breaking older client implementations.

Major versions are specified via the URI of the endpoint and the current major version is v1, for example the whoami call is now: 
Minor versions are date based E.g. 20140101 and are requested via the special request header dA-minor-version. If you do not send the header your client will always receive the latest minor version available.

Note: You do NOT need to update your current clients, all requests that do not contain the /v1/ major version in the URI are locked to v1.0 automatically.

Check out the full versioning documentation.


One of the more inconsistent parts of the old API was its error messages, we have now simplified the error codes and returns to make it easier for your clients to handle error states.

Old style errors are still returned if the request does NOT contain /v1/ in the URI. These will be documented with the endpoint and are marked as deprecated. 

Check out the full errors documentation.

The Future

The point of all this work is to make it possible to release new endpoints in the future. So far we are carefully testing the framework and considering what new endpoints can be released. We don't take the decision to release a new endpoint lightly - it is something that must be well designed, coherent and easy to use and something that we must support for a long time to come.

If you have a burning desire for a particular endpoint that would allow you to do something awesome, then we'd love to hear your thoughts. Please bear in mind that we will only be releasing new endpoints once we are confident that they will work well, be useful to a wide audience and be something we can support log term.


Objective-C deviantART SDK

Mon Feb 10, 2014, 2:33 PM by Pickley:iconpickley:
We're happy to announce the release of version 1.0 of the Objective-C deviantART SDK. This SDK is a simple way to build great experiences using the deviantART API in your Mac or iOS apps.


The SDK requires iOS7 or OS X 10.9 and provides several classes for you to use and interact with:
  • DVNTAPIClient - The core of the SDK. This class provides the OAuth2 management along with core network calls.
  • DVNTAPIRequest - Provides simple wrapper methods around all API deviantART endpoints. If you find any that are missing, feel free to open a pull request to add them.

For the fastest integration, we recommend you use CocoaPods to install the SDK within your project, then simply import DVNTAPI.h with your codebase. DVNTAPI.h imports all the required headers for the SDK to function.

The Foundation

We have built the SDK upon the great foundation that is AFNetworking 2.0, a widely used networking library in the iOS community, this means that the SDK will work on the latest versions of Apple's operating systems, iOS7 and OS X 10.9. We believe this is the best choice as it will allow us not to be held back by the code of the past and allow us to move forward as needed.


To install the SDK within your project, use the below Podfile then run pod install:

platform :ios, '7.0'
pod "deviantART-SDK", "~> 1.0.0"


Atop AFNetworking, we built a layer of OAuth 2.0 abstractions to allow authentication and interaction with the deviantART API. With two method calls to DVNTAPIClient, you can be fully authenticated and ready to make calls to the API.

Simply set your client's ID and secret in the SDK in applicationDidFinishLoading:

[DVNTAPIClient setClientID:@"__CHANGE_ME__" clientSecret:@"__CHANGE_ME__"];
Then authenticate using your client details by calling:

[DVNTAPIClient authenticateFromController:self scope:@"basic" completionHandler:^(NSError *error) {
  if(!error && [DVNTAPIClient isAuthenticated]) {
      // App is fully authenticated with no errors
      // and ready to perform API calls
  } else {
      NSLog(@"Error: %@", error);

After authentication is completed, you can make calls to any API endpoint you need and the SDK will handle authentication for you.


Using DVNTAPIClient as a base, DVNTAPIRequest builds upon its basic GET/POST methods to provide simple methods to call upon any endpoint on the deviantART SDK. Here's an example of retrieving a delta from the API.

[DVNTAPIRequest deltaWithCursor:@"12345" offset:120 success:^(NSURLSessionDataTask *task, id JSON) {
       NSLog(@"JSON Response: %@", JSON);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
       NSLog(@"Error: %@", error);

DVNTAPIRequest covers all current API endpoints but if the need arises, you can use the GET/POST methods on DVNTAPIClient directly and authentication will still be handled completely by the SDK.


For further documentation on getting started using the SDK, check the README file on GitHub. More in-depth Apple style documentation can be found here.

Open Source

The deviantART SDK is open source on GitHub and released under the BSD license. We will be accepting pull requests for changes from you, the community. Guidelines for issues, coding style and pull requests can be found in the project's README file.

We have also submitted the SDK to be available via CocoaPods, the biggest dependency manager for Objective-C projects. This will allow even simpler integration of the SDK into your current or new project.

Developers can be angry people sometimes. This is actually quite the understatement and dt is no exception to that assessment. With web development in particular, there are several moments during the day where we are astounded, perplexed, and irritated by why something works the way it does--often over things beyond our control like lack of uniform web standards. Abe Stanway, the creator of Commit Logs from Last Night, actually gives a pretty compelling, and serious, Ignite talk on the functionality of profanity for developers here:

(It has several cool histograms and visualizations of how developers use profanity and which languages it's most prevalent in--surprise ending: Javascript generates the most profanity)

Last week, we received a very interesting, if not amusing, bug report:

"I just wanted to let you know that the reason why deviantART's CSS isn't loading properly for some people is because one of your CSS files has f*** in a stylesheet comment."

That's right. The almighty F-word was breaking how some stylesheets were loading for deviants who were accessing the site from computers with overly sensitive system-wide profanity filters installed. These users' browsers likely stopped parsing the stylesheet entirely upon reaching the word in the stylesheet, leading to a fairly ugly and/or broken page.

The irony here is that we didn't have to do anything to fix this bug (well, we did have to rename an image file that had a vulgar name!).

Why didn't we have to do anything?

Last week, we made a pretty big switch in how we build stylesheets on deviantART. We started using LESS with the CSS rollup files that we build (deviantART has hundreds of stylesheets--we combine these into single rollup files to reduce the number of requests your browser has to make).  One of the outcomes of this switch was that we no longer serve stylesheets with developer comments left in.

Oops. We're sorry, everyone. We can't promise we'll never swear again. But we can promise if you're browsing deviantART at the public library, our swearing won't stop you from using the site. :)

Upgrading to jQuery 1.9

Sat May 4, 2013, 11:20 PM

One of the most time consuming tasks involved with running a large website can be upgrading libraries. Of course we do this all the time, but sometimes those libraries are used across the entire site. One of those libraries that we use at deviantART is jQuery. Unfortunately, we got a little bit behind with keeping jQuery up to date and we were still on version 1.7. But over the last couple of months, dt has upgraded the whole deviantART network to jQuery 1.9. As you may already know, this upgrade can be slightly challenging due to the number of changes that break backwards compatibility.

The first thing that everyone attempting to upgrade from an earlier version should use is the new jQuery.migrate plugin. This plugin is bundled with jQuery 1.9 and will generate console warnings when deprecated features are used. Without a doubt, this is the most helpful tool available for finding parts of your site that could break. To use the plugin, first include jQuery, then include the migrate plugin:

<script src="/styles/js/jquery.js">
<script src="/styles/js/jquery.migrate.js">

Also make sure that you enable warnings and traces, so that you can gather as much debugging information as possible. To do so, add this immediately after migrate.js:

jQuery.migrateMute = false;
jQuery.migrateTrace = true;

One of the significant changes in jQuery 1.9 is the removal of .live() and .die(), which have been superseded by .on() and .off(). Last summer, during our yearly summit, these calls were almost entirely removed from our JS. The last couple of live/die calls have now been completely removed.

Another significant issue that had to be resolved was the removal of .data('events'). Although very little of our JavaScript actually used this feature, not addressing it would have caused some serious issues. Resolving this was pretty straight forward and just required maintaining our own cache of attached events when necessary.

There were a couple of other small issues, but one of them was extremely important and it isn't terribly well explained in the migration guide: separating .prop() from .attr(). Simply put, .attr() is for changing HTML markup and .prop() is for changing the properties of a JavaScript object. Without jQuery, you would use element.setAttribute() to change the attributes of an element. Properties would be changed by directly assigning a value to them: element.checked, element.className, etc.

Sometimes the HTML markup and the element properties mirror each other, and sometimes they don't. Here are some examples:

An input element without a type attribute is actually a "text" input:

var $node = $('<input>');
$node.attr('type'); // undefined
$node.prop('type'); // "text"

The "checked" attribute of an checkbox only reflects the default state, not the active state:

var node = $('<input type="checkbox" checked="checked">').get(0);
node.checked = false;
node.getAttribute('checked'); // "checked", even though the checkbox was ticked off

The "value" attribute of an input only reflects the default state, not active state:

var node = $('<input type="text" value="foo">').get(0);
// assuming the value changed to "rubber duck" (by typing into the input) before code is run...
node.value; // "rubber duck"
node.outerHTML; // <input type="text" value="foo">
$(node).parent().html() // same as above, even with jQuery
node.getAttribute('value'); // "foo"

Note that jQuery does consider the value of some properties when using .html(), see this example.

The "href" attribute of a relative link does not represent the full link with protocol and domain:

var $node = $('<a href="/test>Test</a>');
$node.attr('href'); // "/test"
$node.prop('href'); // ""

The "selectedIndex" property of a dropdown tells you the currently selected option index:

var $node = $('<select><option>0</option><option>1</option><option selected>2</option>');
$node.attr('selectedIndex'); // undefined
$node.prop('selectedIndex'); // 2

As you can see, there is a very real difference between .attr() and .prop(). For a long time jQuery has been munging the returns of .attr() to reflect property values. Inevitably, this leads to confusion or outright broken code. Although this split is probably one of the most difficult changes to make correctly, we fully support the decision that jQuery has made.

So, in conclusion, what is the best way to use .attr() and .prop()? This is our recommendation:

// Bad
if (cond) {
   $(node).attr('checked', true);
} else {
// Better
$(node).prop('checked', cond);
// Best
node.checked = cond;

dt hopes that this post will help you with your upgrade to jQuery 1.9 and beyond!

Recent Journal Entries

We're Hiring Developers

We're looking for talented web developers to join our team! :la: Interested? Check out…

Journal Writers