Heads up! We’re sunsetting existing migrations on April 3rd.

Update: We are pushing back the original dates listed in this post by two weeks. We will be setting all apps to “current” mode on March 27th. We will be sunsetting all existing migrations on April 3rd.

Although most of our API development effort is focused on delivering new functionality, over the last few months we’ve made a number of tweaks to the existing behavior of the API. Our strategy for making incremental changes to existing functionality in the API without breaking apps is to use migrations. Migrations allow us to introduce new behavior while allowing existing apps to operate in “legacy” mode until they’ve had a chance to update their code.

We currently have four active migrations, three of which have been active since September. These migrations are simple changes to the API and we want to get everyone up-to-date so we can reduce documentation complexity, bugs, etc. To move things along, we will be sunsetting our existing migrations on March 20th April 3rd.

This will be our first time sunsetting any migrations (and there will be new ones in the future) so we want to make sure it goes smoothly for everyone. On March 13th 27th, a week before we sunset the existing migrations (and one month from today), we will set all apps to use “current” mode for all migrations. You will still be able to set these back to “legacy” mode if anything breaks. You can check and adjust the current migration settings for your apps here. Please also check for any instances where you have overridden migration settings on a per-call basis. If all your migrations are already set to “current” and you’re not overriding anything on a per-call basis you do not need to make any changes to your code.

The following is the complete list of existing migrations, along with examples so you can review and make sure your code is good to go:

Response envelope migration - all responses are returned in a response envelope with “data” and “meta” fields.

Legacy Current

{
    ... App.net object fields ...
}

{
    "data": {
        ... App.net object fields ...
    },
    "meta": {
        ... other useful stuff ...
    }
}

Pagination IDs migration – max_id / min_id are always returned as strings rather than ints.

Legacy Current

{
    "data" : [
        ... App.net objects ...
    ],
    "meta":{
        "code" : 200,
        "max_id" : 953737,
        "min_id" : 927539,
        "more" : true 
    }
}

{
    "data" : [
        ... App.net objects ...
    ],
    "meta":{
        "code" : 200,
        "max_id" : "953737",
        "min_id" : "927539",
        "more" : true 
    }
}

Follow pagination migration – follower / following user lists are always paginated.

Legacy Current

{
    "data" : [
        ... complete list of user objects ...
    ],
    "meta":{
        "code" : 200,
        "max_id" : "953737",
        "min_id" : "52",
        "more" : false
    }
}

{
    "data" : [
        ... partial list of user objects ...
    ],
    "meta":{
        "code" : 200,
        "max_id" : "953737",
        "min_id" : "927539",
        "more" : true
    }
}

Disable min/max id migration – when using pagination to request posts, pass since_id or before_id. Note also that the legacy response would include the post matching the supplied id, but the current response does not.

Legacy Current

/stream/0/posts/stream/global?min_id=12345
/stream/0/posts/stream/global?max_id=54321

/stream/0/posts/stream/global?since_id=12345
/stream/0/posts/stream/global?before_id=54321

If you have any questions please contact @orian or join the developer channel.

New Place API

This week we rolled out our Place API, which lets developers query for information about businesses and other places of interest within the vicinity of a provided location. We’re now providing address and contact information as well as categorical tags for more than 60 million places.

Using the +net.app.core.place replacement value you can easily insert place data into any App.net annotation. Even simpler, we provide a ready-made net.app.core.checkin annotation that you can, for example, attach to a post to indicate where it was sent from or attach to a photo uploaded through our File API to indicate where it was taken. You could even add place data to a user’s profile to enable them to indicate where they work.

barmstrong_checkin

To get started adding place data to your app, check out the Place documentation.

New App.net Status Site: adnstatus.net

Here at App.net, we want to make sure that all our developers know exactly how our infrastructure is functioning at any given time, so you can have the most information available to you if we’re having availability issues.

To that end, today we are launching our new status site, adnstatus.net. This site is completely decoupled from our current infrastructure, so even if our primary infrastructure is affected, you’ll be able to get up-to-date information about ADN.

adnstatus.net

We’re also creating a new Operations account on ADN: @adnops. This account, along with the status site, will be used to inform all our users and developers of any problems currently impacting ADN and what we’re doing to restore service.

Looking forward, we plan to start pulling back the curtains on our infrastructure, so stay tuned for some technical-minded blog posts detailing some parts of the App.net core in the coming months.

Collaborating on Annotations and Channel Types

One of the most exciting features of our API is the ability for third party developers to augment objects using annotations and custom channel types. These allow developers to define new fields and behaviors that do not already exist in the API.

While creating new annotations is easy, collaborating on them has been hard. Today we’re taking a step to improve the situation. We’ve created a new object-metadata github repository to track the development of annotations and channel types. This gives developers a central place to share and review each others’ work to extend App.net API objects. If you’re working with annotations or building new channels, please review the github README and contribute!

This is an experiment to see if this approach is helpful. Feedback is always welcome.

New API documentation

Along with the release of the messaging API, we rolled out a new version of our documentation at developers.app.net. Our goal was to make the documentation easier for developers to consume and for us to maintain. We’ve reworked the organization of docs and over the next few days and beyond you’ll see continued improvement to the content and presentation.

We know that providing great documentation is critical for developers to build great apps.  If you have suggestions for how to improve the docs, contact @orian or issue a pull request – all the source for our new documentation still resides on Github in a new branch.

API Highlight: Interactions

A nice feature in social applications is to get feedback on who recently connected with you or interacted with your content. We wanted to make it easy for our developers to get this data in a form that is ready for display without a lot of work. Using the Interactions endpoint you can retrieve a stream of recent Interactions with a user and their content, such as when they are followed or when someone replies to, reposts or stars one of their posts.

We hope this is a useful resource particularly for developers who are building general-use clients. To see some implementations of the Interactions stream check out ANAC (which also displays the raw JSON) as well as Treeview and Appnetizens.

We’re always interested in your feedback. Let us know if your app incorporates Interactions!

New API feature: Stream Marker

Multiple times a day, I switch between my laptop and my phone. It’s frustrating that I have to ask myself “have I seen this post?” as I scroll through My Stream. Today we’re adding support for Stream Markers to the API. This will allows clients to sync where you are in your stream, global, and even in individual threads between clients.

In the response envelope for all streams that support markers, there will now be a Stream Marker object. If a marker hasn’t been set, it will just include the name of the stream so you can set a marker:

$ curl -H 'Authorization: BEARER [access token]' "https://alpha-api.app.net/stream/0/posts/stream/unified"
{
    "data": [...],
    "meta": {
        "code": 200,
        "marker": {
            "name": "unified"
        },
        "max_id": 65009,
        "min_id": 65009,
        "more": true
    }
}

If a marker has been set, it will include information about when the marker was last updated including the Post ID of the post at the top of the window, a timestamp, and an opaque value representing the version of this marker so you can easily see if it’s been updated.

$ curl -H 'Authorization: BEARER [access token]' "https://alpha-api.app.net/stream/0/posts/stream/global"
{
    "data": [...],
    "meta": {
        "code": 200,
        "marker": {
            "id": "50000",
            "name": "global",
            "percentage": 0,
            "updated_at": "2012-11-09T23:35:38Z",
            "version": "NWoZK3kTsExUV00Ywo1G5jlUKKs"
        },
        "max_id": 65109,
        "min_id": 65109,
        "more": true
    }
}

Stream Markers aren’t meant to broadcast a User scrolling through a stream in real time so we recommend that you only update a marker when a user is changing to a different stream, closing the client, or has stopped scrolling for at least 10 seconds. To update a marker, just POST a JSON dictionary that matches our Stream Marker schema with the correct stream name:

$ curl -H 'Authorization: BEARER [access token]' -H "Content-Type: application/json" -X POST -d '{"name": "global", "id": 50001}' "https://alpha-api.app.net/stream/0/posts/marker"
{
    "data": {
        "id": "50001",
        "name": "global",
        "percentage": 0,
        "updated_at": "2012-11-12T22:24:04Z",
        "version": "G2RTiSRzpGfQc3LUXrBavCAxZHo"
    },
    "meta": {
        "code": 200
    }
}

If you store the “version” that’s returned, you’ll be able to tell when a user has changed position on a different client and update accordingly.

Currently the following streams can be marked:

  • Global Stream
  • My Stream
  • Unified Stream
  • My Mentions
  • An individual user’s stream of posts
  • A hashtag stream
  • The replies stream for a post

As always, let us know if you have any feedback through any of the developer support channels listed here.

New Developer Wiki

One of our goals here at App.net is to provide great documentation for our developers so they can quickly find the resources they need. We’re working on revamping our docs to be easier to navigate. In the meantime, we just put up a new starting point on our Developer Wiki for devs to get familiar with the resources available to them.

Also, a new Developer Resources page lists a growing collection of libraries, tools and other third party contributions that you can use to build great apps. We’re always looking for feedback and encourage you to add useful resources that you’ve authored or discovered.

Developer Test Accounts

Developers have been asking us for test accounts for a little while now. We heard you loud and clear. Each developer account now has the ability to create two member tier accounts at $5 per year, per account.

To access, go to the Discounted Users page under My Settings in Alpha (must have a Developer account). Click Create a new promo code, which generates a link to signup for a discounted account.

That link takes you to our signup page, and you’ll see that the code has been applied.

As always, email dev-support@app.net with any questions or issues.

API: Friday Features

In case you missed the post from @mthurman earlier today, we rolled out some new features today to our API:

  1. The API now allows custom links in post text
  2. Machine only posts can have mentions
  3. If you don’t want to store stream ids (or if you just want to name your streams), check out the new stream.key parameter

We’re going to start posting API updates from @ADNAPI, so be sure to follow.

Just another day in office here. Have a good weekend, and see you at the hackathon.