Short labels for tight spaces
A score tile on a phone has room for perhaps three or four characters per team. A league table with ten columns has little room for long club names. Short codes solve that layout problem, and the abbreviations directory supplies them. It takes no parameters and returns codes for the teams the source covers, cached for about an hour.
Unusually for our catalogue, we can point to where the codes sit. The short codes are available as JSON under data.teams.team in the response. Identifiers and source attributes inside that structure are preserved as strings, with at-sign prefixed attribute names for values that came from source attributes. Read a sample to see exactly which attribute carries the team identifier and which carries the code, and map from that.
Everything else about the envelope is standard: meta records the feed, UTC fetch time, cache time and qualification.
A code is not an identifier
Short codes look like identifiers, and that is the danger. They are not unique across the football world: the same three letters can belong to clubs in different countries, and a club's code can change after a rename. If you key data on codes, two different clubs will eventually share a row, or one club will split into two.
Use the team identifier as the key everywhere, in your database, URLs and joins. Look up the code at render time, from a table keyed by that identifier, and use it only for display.
- Key everything on the string team identifier.
- Use codes only for display.
- Fall back to the supplied team name when a code is missing.
- Never generate your own codes and present them as supplied.
Building a code lookup table
The example fetches the directory once a day, walks the entries under data.teams.team and stores a code per team identifier. The attribute names in the example are placeholders for whichever at-sign prefixed attributes your sample uses; do not copy them without checking.
const res = await fetch("https://footballapi.net/api/v1/football/abbreviations", {
headers: { "X-API-Key": process.env.FOOTBALLAPI_KEY },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.code} ${body.requestId}`);
const entries = [].concat(body.data?.teams?.team ?? []);
for (const t of entries) {
// replace ID_ATTR and CODE_ATTR with the @-prefixed names in your sample
await saveCode(String(t[ID_ATTR]), t[CODE_ATTR]);
}A detail worth defending against
Structures converted from XML sometimes represent a list with one entry as a single object rather than a one-item array. The example guards against that by wrapping the value in an array before iterating. It is a small defensive habit that prevents a whole class of bugs in which code works for a full directory and breaks the day a filter or source change leaves a single team.
The same habit applies elsewhere in the catalogue wherever data comes from a source structure. Write your mapping so that one, many or none are all handled without special cases in the calling code.
Codes and accessibility
Three-letter codes are compact for sighted readers and confusing for screen reader users, who will hear letters spelled out. When you display a code, give the element an accessible name with the full team name, for example through a visually hidden label or an abbreviation element with a title. Readers who know the codes get the compact view; everyone else still knows which team is meant.
Consider your audience too. Codes familiar in one country may be opaque in another. On wider screens, show the full supplied name and reserve codes for genuinely narrow layouts.
When codes collide on one screen
Occasionally two teams that appear together, perhaps in a multi-competition score strip, share a code. The supplied data will not resolve that for you. Detect duplicates on the screen you are rendering and fall back to the full name, or add the competition as context, for the colliding entries. Do not modify the codes themselves in storage; the collision is a display problem and belongs in display logic.
Keep a small editorial override table for codes your editors prefer, keyed by team identifier, and apply it at render time on top of the supplied codes.
Where short codes earn their place
Codes are most valuable in a few specific places: score tiles and tickers on narrow screens, the team columns of dense tables, chart labels where long names overlap, and push notification titles with strict length limits. In each case, the full name should be available nearby or through an accessible label. Outside those places, full names read better and avoid ambiguity. A match page heading, for example, should use full supplied names; there is plenty of room and readers arriving from search may not know the codes.
Decide per component, write the rule down in your design system, and apply it consistently.
How often codes change
Codes change rarely: after a rename, a merger or a source correction. A daily refresh of the directory is more than enough, and a weekly one is reasonable for most products. Compare each new copy with the previous one by team identifier and log any changed codes. A changed code is worth a quick human check, because it often accompanies a rename that you will also want to reflect in profile pages and editorial content.
If a team identifier disappears from the directory, keep its last known code in your table so old pages still render, and mark it as no longer supplied.
Codes in multilingual products
Short codes are often based on one language's version of a club name. In a multilingual product, a code that is obvious to readers in one country can be cryptic in another. The supplied codes are what the source provides; they are not localised by us. If you serve several languages, consider showing full names more often in locales where codes are less familiar, and keep any locale-specific editorial codes in your own override table, clearly separated from supplied data.
Reading the directory structure
Codes sit under data.teams.team in the response. Map each entry to a team identifier and a code once, from a saved sample, and store the pairs in a table keyed by the identifier. Your components then look codes up by identifier and fall back to the full supplied name when no code exists. Never derive a code by truncating a name; it produces collisions and labels clubs do not use.
Plan scope
The abbreviations directory is a global service that requires Growth at EUR 99 a month or Pro at EUR 249, and it is not included in Starter. It also requires the service to be activated for your account. Starter keys receive a 403 response with the subscription_required code, which is not billed. Starter products can use supplied team names, with their own editorial short labels if needed.
A daily refresh is one successful request. Requests above the daily inclusion cost EUR 0.002 each on the monthly EUR invoice. There is no free trial, and no VAT is currently charged.
Questions developers ask
- Where are the short codes in the response?
- Under data.teams.team, with identifiers and source attributes preserved as strings and at-sign prefixed attribute names.
- Can I use a short code as a team key?
- No. Codes are not unique and can change. Key everything on the team identifier.
- Does abbreviations take parameters?
- No. One request returns the directory.
- Is the directory on Starter?
- No. It requires Growth or Pro and is not included in Starter.
- What if a team has no code?
- Fall back to the supplied team name. Do not generate a code and present it as data.
Guides and documentation
Check the plan before you write the integration.
Starter EUR 29, Growth EUR 99, Pro EUR 249 per month. No free trial. No VAT currently charged.