URL Generation Guide for Frontend Developers

URL Generation Service Guide

Overview

As part of our content management system (CMS), we need to implement a URL generation feature for certain resources. Your role is to create an API endpoint that will generate appropriate URLs based on the resource data provided.

Key Points

  • Our URL Generation service will make requests to your API when a URL needs to be created or updated
  • You will receive the full resource data for URL generation
  • Only whitelisted resource types will be sent to your API for URL generation
  • The generated URLs are managed automatically; CMS editors or other tools cannot manually alter these URLs
  • The endpoint for URL generation will be configurable per tenant
  • The service supports generating URLs for entity tags that have been added to articles/videos/galleries
  • Not all available entity tags will trigger URL generation requests - only those that content has been tagged with

Currently supported resources

  • ARTICLE
  • CATEGORY
  • GALLERY
  • VIDEO
  • TAG
  • ENTITY_TAG

API Specification

Endpoint

You need to implement an endpoint for URL generation. The exact endpoint URL will be configurable per tenant.

Request Format

The request will be sent as JSON in one of two formats depending on the resource type:

Standard Resources

{
  "project_domain": "string",  // This is the tenant identifier
  "id": "string",
  "type": "string",
  "action": "string",
  "object": {
    "data": {
      // Varies by resource type
      // Structure will be the same as GET /{resource}/{id} in Content API
    }
  }
}

Entity Tags

Example of a Football team entity (using numeric ID):

{
    "id": "team-34",
    "type": "ENTITY_TAG",
    "action": "UPDATED",
    "object": {
        "data": {
            "id": "team-34",
            "title": "Лудогорец",
            "data": {
                "country": {
                    "id": 14,
                    "name": "България",
                    "slug": "balgaria-14",
                    "assets": null,
                    "urlFlag": "https://image.api.integration.sportal365.com/process/smp-image-api-shared-region-integration/assets/country/flag/14-Bulgaria-flag.png",
                    "translations": [],
                    "display_asset": {
                        "url": null
                    }
                },
                "url_logo": "https://image.api.integration.sportal365.com/process/smp-image-api-shared-region-integration/assets/18062021/1624016476699.png?operations=autocrop(150:150)",
                "entity_type": "team",
                "gender": "MALE",
                "origin_ids": [],
                "id": 34,
                "title": "Лудогорец",
                "uuid": "8aae918e-9f60-4dff-bde2-d4bb16855ce1",
                "slug": "ludogorets-34"
            },
            "provider": "football-api",
            "urls": {
                "canonical_url": null
            },
            "language": "bg",
            "entity_type": "team",
            "created_at": "2024-11-27T07:15:39.773Z",
            "updated_at": "2025-01-23T14:34:02.962459465Z",
            "external_id": "34",
            "persistence_status": "UPDATED"
        }
    },
    "project_domain": "sportal.bg",
    "request_origin": null
}

Example of a Basketball competition entity (using UUID):

{
    "id": "competition-03de9b67-828d-4e26-b6eb-1fc335712706",
    "type": "ENTITY_TAG",
    "action": "CREATED",
    "object": {
        "data": {
            "id": "competition-03de9b67-828d-4e26-b6eb-1fc335712706",
            "title": "НБА",
            "data": {
                "country": {
                    "id": "1ceea60e-b0f8-4f7f-9074-4049bfa3dc1c",
                    "name": "САЩ",
                    "slug": "sasht-saqZK24UZj9LOsTXFvxvQ",
                    "assets": null,
                    "urlFlag": null,
                    "translations": [
                        {
                            "name": "САЩ",
                            "address": null,
                            "language": "bg",
                            "short_name": null,
                            "three_letter_code": "САЩ"
                        }
                    ],
                    "display_asset": {
                        "url": "https://image.api.integration.sportal365.com//process/smp-image-api-shared-region-integration/sports-data-sportal365-integration/15082024/5751c66c-1f54-49fa-b0de-2d324b1bf6f2.svg?operations=fit(150:150)"
                    }
                },
                "birthdate": null,
                "gender": "MALE",
                "display_asset": {
                    "url": "https://image.api.integration.sportal365.com//process/smp-image-api-shared-region-integration/basketball/06102023/207d3381-0375-4a6b-bd06-4fbeaf759183.png?operations=fit(70:70)",
                    "flag": {
                        "url": null
                    },
                    "logo": {
                        "url": null
                    }
                },
                "type": null,
                "title": "НБА",
                "entity_type": "competition",
                "translated_name": null,
                "id": "03de9b67-828d-4e26-b6eb-1fc335712706",
                "sport": "basketball",
                "slug": "nba-7IhwBn7DUdiRZcqoSTsEo",
                "country_id": "1ceea60e-b0f8-4f7f-9074-4049bfa3dc1c"
            },
            "provider": "sports-search-api",
            "urls": {
                "canonical_url": null
            },
            "language": "bg",
            "entity_type": "competition",
            "created_at": "2025-01-24T07:19:40.775091425Z",
            "updated_at": "2025-01-24T07:19:40.775091565Z",
            "external_id": "03de9b67-828d-4e26-b6eb-1fc335712706",
            "persistence_status": "CREATED"
        }
    },
    "project_domain": "sportal.bg",
    "request_origin": null
}

Example of a Football match

{
  "id": "match-9381436",
  "type": "ENTITY_TAG",
  "action": "CREATED",
  "object": {
    "data": {
      "id": "match-9381436",
      "title": "Newcastle United - Arsenal",
      "data": {
        "goal_away": 0,
        "finished_at": "2025-02-05T21:55:15+00:00",
        "minutes": null,
        "blacklist": null,
        "type": null,
        "title": "Newcastle United - Arsenal",
        "away_team": {
          "id": 97,
          "name": "Arsenal",
          "slug": "arsenal-97",
          "type": "club",
          "uuid": "a7453a80-b50d-46b6-a974-0f56f2a06ee5",
          "gender": "MALE",
          "url_logo": "https://image.api.integration.sportal365.com/process/smp-image-api-shared-region-integration/assets/team/logo/97-Arsenal-logo.png",
          "short_name": null,
          "three_letter_code": "ARS"
        },
        "start_time": "2025-02-05T20:00:00+00:00",
        "entity_type": "match",
        "round": "Semi Finals",
        "updated_at": "2025-02-06T10:14:14+00:00",
        "goal_home": 2,
        "live_updates": null,
        "started_at": "2025-02-05T21:06:03+00:00",
        "tournament_season_stage": {
          "id": 6374866,
          "cup": true,
          "name": "EFL Cup",
          "slug": "efl-cup-6374866",
          "uuid": "6af8685e-198e-4e78-98d3-26b679eaafa3",
          "country": {
            "id": 15,
            "name": "England",
            "slug": "england-15",
            "uuid": "97db171c-4b7e-4935-bbd1-cc2e7f052629",
            "url_flag": "https://image.api.integration.sportal365.com/process/smp-image-api-shared-region-integration/assets/country/flag/15-England-flag.png"
          },
          "tournament_id": 76,
          "tournament_season_id": 6374865
        },
        "id": 9381436,
        "home_team": {
          "id": 103,
          "name": "Newcastle United",
          "slug": "newcastle-united-103",
          "type": "club",
          "uuid": "b335a3f0-a603-48e3-a14b-fa6bf70d6b55",
          "gender": "MALE",
          "url_logo": "https://image.api.integration.sportal365.com/process/smp-image-api-shared-region-integration/assets/team/logo/103-Newcastle-United-logo.png",
          "short_name": null,
          "three_letter_code": "NCU"
        },
        "slug": "newcastle-united-arsenal-9381436",
        "lineup_available": true,
        "event_status": {
          "id": 1,
          "code": "finished",
          "name": "Finished",
          "type": "finished",
          "uuid": null,
          "short_name": "Finished"
        }
      },
      "provider": "football-api",
      "urls": {
        "canonical_url": null
      },
      "language": "en",
      "entity_type": "match",
      "created_at": "2025-02-12T13:42:41.568553926Z",
      "updated_at": "2025-02-12T13:42:41.568554726Z",
      "external_id": "9381436",
      "persistence_status": "CREATED"
    }
  },
  "project_domain": "smp.demo",
  "request_origin": null
}

Supported Entity Types

The service supports URL generation for the following entity types:

Sports Entities:

  • player
  • team
  • match
  • tournament (used in Football)
  • competition (equivalent to tournament, used in other sports)
  • venue
  • coach
  • referee
  • game
  • arena
  • horse
  • race
  • circuit

Custom Entities:

  • person
  • organization
  • place

Important Notes About Entity IDs

  • Football entities use numeric IDs for legacy reasons (e.g., "team-34", where 34 is the numeric ID)
  • Basketball, Tennis, Ice Hockey and all other sports in the platform use UUIDs (e.g., "competition-03de9b67-828d-4e26-b6eb-1fc335712706")
  • For sports hierarchy, 'tournament' (Football) and 'competition' (other sports) represent the same entity type

Response Format

Your API should respond with a JSON object containing the generated URL:

{
  "url": "string"
}

Error Handling

If there's an error in URL generation, respond with an appropriate HTTP status code (e.g., 400 for bad request, 500 for server error) and include an error message in the response body:

{
  "error": "string"
}

Implementation Guidelines

Resource-specific Logic

  • Implement URL generation logic for each whitelisted resource type
  • The structure of the object.data in the request will vary based on the resource type
  • Handle both standard resources and entity tags appropriately
  • Consider the differences between Football and other sports' entity types

Tenant-aware

  • Use the project_domain to generate tenant-specific URLs
  • Consider tenant-specific requirements for URL structure

Action-aware

  • The action field in the request may indicate the type of operation (e.g., "create", "update")
  • Consider this when generating URLs if necessary

Idempotency

  • Ensure that your URL generation is idempotent
  • Given the same input data, it should always produce the same URL

Performance

  • Optimize your URL generation logic for performance, as it may be called frequently
  • Consider caching strategies where appropriate

Validation

  • Implement proper input validation
  • If required data is missing or invalid, return an appropriate error response
  • Validate entity types against the supported list

Next Steps

  1. Implement the URL generation endpoint according to this specification
  2. Ensure the endpoint can handle both standard resources and entity tags
  3. Make sure that the endpoint returns the correct URL according to tenant-specific rules
  4. Handle the differences between Football and other sports entity types appropriately
  5. Optimize the endpoint for performance
  6. Implement comprehensive testing for all supported entity types
  7. Email support with the endpoint and the resources that need to have URLs generated