My favorites | English | Sign in

FeedBurner API (Deprecated)

FeedFlare Developer Guide

Introduction

The FeedFlare API (FlareAPI) allows anyone to extend our existing FeedFlare service. Provide new actions and incorporate outside services to make your content more interesting and engaging — both in your FeedBurner feed and on your website.

This document assumes you are a web application developer familiar with XML and one or more server-side programming structures, such as Perl, Cold Fusion, Java/JSP, ASP, or Ruby. Server-side language skills are required in order to create "dynamic" FeedFlare units, which are described in more detail below.

Note: In the XML code samples below, the symbol is used to indicate a linebreak used for spacing in the middle of long, unbroken string (such as a URL). If you copy and paste the code, you will want to remove this character and stitch the string back together at the point this symbol appeared.

FeedFlare Units

The code that defines how FeedFlare should operate is encapsulated in a FeedFlare Unit file. This is an XML document that tells FeedBurner how to render a FeedFlare in the feed and on the site, and it identifies the communication channels that need to be established when creating an instance of a FeedFlare. Every FeedFlare unit is ultimately identified by a URL that either FeedBurner or a third party maintains.

A FeedFlare unit has two pieces of information: catalog information and the instructions for generating an instance of a FeedFlare. Additional attributes and behaviors will be added over time. There are two main classifications for a FeedFlare unit: static or dynamic. A static FeedFlare unit (represented by a <FeedFlare> element in the unit XML) generates FeedFlare that does not change its text or image over time, while a dynamic FeedFlare unit (represented by a <DynamicFlare> element in the unit XML) might change its representation based upon the item data over time. A FeedFlare that says "Email This" would most likely be static, while a FeedFlare that says "There are 3 comments ... add yours now!" would be dynamic (because the number of comments would most likely increase over time). In both cases, the flare link destination will likely be variable based upon information from the feed or item.

FeedFlare Unit Examples

Example 1: Hello, World

Ah, Hello World, my old friend. We meet again. Let's say that we want to create a FeedFlare unit that just says "Hello, World" and nothing else. It's so featureless it doesn't even offer a link to click on, but we have to start somewhere.

Here's what this FeedFlare unit looks like:

    <FeedFlareUnit>
        <Catalog>
            <Title>Hello World 1</Title>

            <Description>A static FeedFlare unit that just shows the text "Hello, World"
            </Description>
        </Catalog>
        <FeedFlare>
            <Text>Hello, World</Text>
        </FeedFlare>

    </FeedFlareUnit>

To create this FeedFlare unit, we have to create an XML file and then host it somewhere so it has a URL FeedBurner can read.

Aside: Where do I put this XML file?

The XML file that describes a FeedFlare unit needs to be addressable by a public URL, so that means it needs to be hosted on a server somewhere so it can be periodically retrieved by FeedBurner. Here are suggestions for where you can host this file:

  1. Use your blog. Most blog engines allow you to upload files (like images) so you can reference them. Go ahead and do that with your FeedFlare unit file, and wherever your blog engine puts the file, there you are.
  2. Use any old HTTP server. If you have access to a web server, just stick the XML file in some directory that will be served by the HTTP server.

We have hosted this file at http://www.feedburner.com/fb/static/flareunits/HelloWorld1.xml. Publishers can now log in to FeedBurner, select the FeedFlare service, and enter that URL. Save the feed, take a look, and you should see your "Hello, World" nice and proud at the bottom of every feed item.

Example 2: See Related Pages

Hello World

Let's do something a little more interesting. Let's create a FeedFlare unit that links to web resources that might be related to the current item. To do that, we'll need to do some variable substitution.

The neat thing about FeedFlare is that the unit has the entire context of the item (including the rest of the feed) available for these variable substitutions. So, if you want to get the item's title, you can just put ${title} in the text of the FeedFlare and the current item's title will be substituted in there. Another variable that is available is the item's link: ${link}. We'll talk about more powerful XPath variable substitutions below, but for now we can use Google's "similar pages" query and construct a FeedFlare unit like this:

    <FeedFlareUnit>
        <Catalog>

            <Title>See Related Pages at Google</Title>
            <Description>A static FeedFlare unit that links to a Google page that shows
            pages that are similar to the current item</Description>
        </Catalog>
        <FeedFlare>
            <Text>Hello, see related pages</Text>

            <Link href="http://www.google.com/search?as_rq=${link}"/>
        </FeedFlare>
    </FeedFlareUnit>

It seems to work, and now when a reader clicks on the FeedFlare they are taken to a page with related links. You can find this file at http://www.feedburner.com/fb/static/flareunits/HelloRelated.xml.

Example 3: Personalized Hello

Let's make the greeting a bit more personalized. Many times, the author or publisher's name is present in the feed. So let's do a couple of things .. let's say "Hello from (author)" and then link to the blog home page. We saw before that there are a few "shortcut" variables like title, but you as a FeedFlare developer have the full power of XPath at your disposal. You can construct XPath variable substitutions, so if you'd like the feed's title you could use an expression like ${../title}, which would get the item's parent's title, i.e. the feed title.

Now, that's not exactly true. The actual expression you'd need to use is ${../a:title}. When you do XPath variable substitution, each element needs a "namespace prefix", and the "normal" feed elements have the prefix "a". You also can define other namespaces to use.

"But wait," you exclaim. "There are all sorts of different feed formats. Do I have to provide different XPaths for different formats? That's sheer madness." Good question. The answer we are happy to offer is an emphatic "no." If you use XPath variable substitution, FeedBurner will automatically convert your feed to an Atom 1.0 feed behind the scenes and use that for the XPath. This doesn't mean that your RSS 2.0 feed will now be delivered as an Atom 1.0 feed; it just means that, for the purposes of doing this variable substitution, FeedBurner works on an Atom 1.0 copy of the feed to grab the appropriate information.

That's plenty of talk; let's see what this FeedFlare unit looks like:

    <FeedFlareUnit>
        <Catalog>
            <Title>Hello World 2</Title>
            <Description>A static FeedFlare unit that says hello from
            the author and links to the main web page</Description>

        </Catalog>
        <FeedFlare>
            <Text>Hello from ${(ancestor-or-self::*/a:author/a:name)[last()]}</Text>
            <Link href="${../a:link[(@rel='alternate' or not(@rel))]/@href}"/>
        </FeedFlare>

    </FeedFlareUnit>

So, this is more complex than your average FeedFlare unit. But let's walk through it. This is a static FeedFlare, since the link and text we construct never changes. Both the text and the link are using variable substitution. There are a bunch of common XPath expressions listed in the Common XPath Expressions section of the document, but let's look at these:

  • ${(ancestor-or-self::*/a:author/a:name)[last()]}
    What this is saying is that if there's an author element (with a name subelement) on the current item, use that, otherwise use the item's ancestor's (i.e., the feed's) author name element.
  • ${../a:link[(@rel='alternate' or not(@rel))]/@href}
    This should resolve to the blog's address, which is specified by the href attribute of the feed's link with rel="alternate" or the feed's link with no rel attribute (since if the rel attribute is not specified, it represents the alternate location ... see the rel attribute documentation for more information).
Hello World

When all is said and done and we put this FeedFlare unit at some URL (we have it at http://www.feedburner.com/fb/static/flareunits/HelloWorld2.xml), we get some new FeedFlare (provided your feed has an author element specified for it):

Example 4: Hello Back At Ya!

Let's try a dynamic FeedFlare unit. How about we greet the name of the person who made the most recent comment? This is going to change over time, so we need to make this a dynamic FeedFlare unit. We're going to assume here that the publisher is using the Atom Feed Thread Extension framework, but you could also adapt this to support the wfw Comment API.

In a dynamic FeedFlare unit, you are constructing a URL that will be periodically called by FeedBurner, and it is the responsibility of that URL to return an XML document that represents a FeedFlare. That means you need to have some server-side programming language skills to be able to create dynamic FeedFlare units.

Let's look at this FeedFlare unit

    <FeedFlareUnit>
        <Catalog>
            <Title>Hello, Visitor</Title>

            <Description>Greet the person who made the most recent 
        comment to the current post.</Description>
        </Catalog>
        <DynamicFlare href="http://www.feedburner.com/fb/dynamicflares/HelloVisitor.jsp?
        feedUrl=${a:link[@rel='replies']/@href}"/>
        <SampleFlare>

            <Text>Hello, Crawford Matrix. Thank you for your comment!</Text>
        </SampleFlare>
    </FeedFlareUnit>

When FeedBurner sees a new item and applies this FeedFlare unit to that item, it does the variable substitution to construct a URL that it will call periodically. This URL is only constructed once, but it is expected that the results that the URL returns will change over time. If an XPath variable substitution cannot be resolved (i.e., the feed is not using the Feed Thread Extension), then a FeedFlare will not be created for that item.

To continue with the example, let's say an item in the feed looks like this:

    <entry>
        <title>Increasingly disenchanted with backgammon</title>
        <link rel="replies" type="application/atom+xml"
        href="http://www.majordojo.com/2006/01/increasingly_di-comments.xml" thr:count="9" />
        <link rel="service.edit" type="application/atom+xml"
        href="http://www.majordojo.com/movabletype/mt-atom.cgi/weblog/blog_id=3/entry_id=1042"
        title="Increasingly disenchanted with backgammon"/>
        <id>tag:www.majordojo.com,2006://3.1042</id>

        <published>2006-01-03T23:25:39Z</published>

        ...

    </entry>

FeedBurner sees this item and constructs the following URL that it will call periodically:

GET http://www.feedburner.com/fb/dynamicflares/HelloVisitor.jsp?feedUrl=http://www.majordojo↵ .com/2006/01/increasingly_di-comments.xml

(In this example, we're using a feedburner.com address for the DynamicFlare URL, but it is expected that these will be hosted on many third party sites, including yours.) When FeedBurner calls this URL, it expects a response that contains a FeedFlare element:

    <FeedFlare>
        <Text>Hello, Crawford Matrix. Thank you for your comment!</Text>
        <Link href="http://www.majordojo.com/2006/01/increasingly_di.php#11356"/>

    </FeedFlare>

FeedBurner will make sure that the latest value for the dynamic FeedFlare unit is displayed in the feed — without the item showing up as modified. Cool, huh? The FeedFlare will also be updated on the site.

One more thing to mention about this example. You may wonder what the SampleFlare element is. When a publisher wants to add your FeedFlare unit to their feed, the SampleFlare serves as an example of what the FeedFlare might look like. FeedBurner won't have an actual feed to use the DynamicFlare to generate a FeedFlare, so that's why a SampleFlare is required for dynamic FeedFlare units. You can also provide a SampleFlare element with static FeedFlare units, but it's not required.

Example 5: Monkey Alert!

One thing to note with dynamic FeedFlare units is that, at this point, FeedBurner only supports a GET query to retrieve the FeedFlare. That means that you are somewhat limited in the information that you can pass to the DynamicFlare URL — passing in the entire content of an item, for example, will most likely result in a GET request that is too long. We plan on supporting the POST method in a later iteration, which would address this limitation, but for now you might have to get creative if you want to create a FeedFlare unit that operates on the content of an item.

As an example, let's say that you want to create a FeedFlare unit that simply displays "Monkey Alert!" if an item's content references, well, a monkey (thank you Jon Klem for this demented example). One can get creative with some XPath functions to achieve this result:

    <FeedFlareUnit>

        <Catalog>
            <Title>Monkey Alert!</Title>
            <Description>Show an alert if the post contains the word "monkey"</Description>
        </Catalog>
        <FeedFlare>

            <Text>Monkey Alert for "${.[count((a:content//text())[contains(.,'monkey')])
            &gt; 0]/a:title}"!</Text>
        </FeedFlare>
    </FeedFlareUnit>

The text of this static FeedFlare unit (which is found at http://www.feedburner.com/fb/static/flareunits/MonkeyAlert.xml) will only evaluate if a content object associated with the item contains the word "monkey". I'm sure publishers are rushing right now to include the Monkey Alert FeedFlare unit in their feeds.

Other Examples

The best way to learn how to create a FeedFlare unit is to probably find one that pretty much does what you want, and then adapt it. To that end, FeedBurner is maintaining a list of numerous FeedFlare examples that can be "adapted" to your own needs. If you create a FeedFlare unit that you'd like to share, visit the FeedBurner for Developers forum.

Official FeedFlare: Static Examples

Tips for Testing

For starters here is a FeedFlare unit XML quick reference. Also, here are a few tips to help developers create new FeedFlare units.

  1. Reference the FeedFlare unit DTD and validate against it. The DTD is shown below and can be referenced at http://www.feedburner.com/fb/static/flareunits/FeedFlareUnit-1.0.dtd. Use this DTD and a validating XML editor to make sure you're creating valid FeedFlare units.
  2. Use unique URLs when you are in the development phase. When FeedBurner retrieves your FeedFlare unit, we will cache that XML file for some time before checking the source again. While this is appropriate when your FeedFlare unit is being used, it can be frustrating when you are making frequent changes to the XML file and you want to observe the results. One trick is to add a bogus parameter to the end of the FeedFlare unit URL: so, instead of using the URL http://www.yourdomain.com/flare/myflair.xml, start out by using the URL http://www.yourdomain.com/flare/myflair.xml?version=1 or something like that, and then just increment the version number every time you edit the XML file. This will force FeedBurner to retrieve the latest version of the file when it is used for the first time.
  3. Remember to use the "a:" namespace prefix in your XPath expressions. If you want to reference the Atom elements in the feed, remember that we have already bound the "a" prefix to the Atom namespace — there is no default namespace in an XPath expression. If you'd like to reference other namespaces, just declare them on the containing element using the usual xmlns:prefix mechanism.

Common XPath Expressions

Since a FeedFlare unit is a static XML file, the variability comes from, well, variables in the link and text declarations. Basically, a FeedFlare unit has access to the context of the item and its feed container. FeedBurner normalizes the item to an Atom 1.0 item with a feed container, and the publisher can include any XPath as a variable in the elements that support variability. We currently support XPath 1.0, but we will upgrade to XPath 2.0 soon. Please note that the "current node" for that XPath expression will be the <entry> element that represents the current item. Here is a list of some common variable substitutions:

Variable Description
${a:updated} The last updated date for the item, in ISO 8601 format. This is the same as ${./a:updated}.
${a:category[1]/@term} The first listed category.
${../a:title} The feed title. This is the same as ${/a:feed/a:title}.
${../a:link[(@rel='alternate' or not(@rel))]/@href} The HTML page for this feed.
${(ancestor-or-self::*/a:author/a:name)[last()]} The author's email address: the item-level takes precendence

The Atom 1.0 namespace is available with the "a" prefix. Other namespaces can be declared on the containing element and referenced in the expression.

A few of the variables are used so often there are "shortcuts" for them:

Variable Description
${link} The item link. Generally the same as ${a:link[rel='alternate']/@href}
${title} The item title. Generally the same as ${a:title[type='text']}
${feedUrl} The URL of the feed itself. Generally the same as ${a:feed/a:link[rel='self']/@href}

FeedFlare DTD

Here is the DTD for the FeedFlare unit file:


<!ELEMENT FeedFlareUnit (Catalog, ((FeedFlare,SampleFlare?) | (DynamicFlare,SampleFlare)))>
<!ELEMENT Catalog (Title, Description, Link?, Author?)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Description (#PCDATA)>
<!ELEMENT Link EMPTY>
<!ATTLIST Link href CDATA #REQUIRED>
<!ELEMENT Author (#PCDATA)>
<!ATTLIST Author email CDATA #IMPLIED>
<!ELEMENT FeedFlare (Text?, Image?, Link?)>
<!ELEMENT Text (#PCDATA)>
<!ELEMENT Image EMPTY>
<!ATTLIST Image src CDATA #REQUIRED>
<!ELEMENT DynamicFlare EMPTY>
<!ATTLIST DynamicFlare href CDATA #REQUIRED>
<!ATTLIST DynamicFlare method CDATA #IMPLIED>
<!ELEMENT SampleFlare (Text?, Image?)>

And here is the DTD for the XML that is returned from a dynamic FeedFlare call:

<!ELEMENT FeedFlare (Text?, Image?, Link?)>
<!ELEMENT Text (#PCDATA)>
<!ELEMENT Image EMPTY>
<!ATTLIST Image src CDATA #REQUIRED>
<!ELEMENT Link EMPTY>
<!ATTLIST Link href CDATA #REQUIRED>