Welcome to the apetito Developer Portal

Use this portal to register your applications and integrate with our data.

Use our helpful quick starts below to start integrating with our data at lightning speed using your framework of choice.

  1. Register a new single-page application with the offline_access, openid, profile, and Products.Read.All scopes.
  2. Install the Angular CLI.
    npm install -g @angular/cli

    More information about setting up a local Angular environment.

    You are welcome to skip this step if you have already installed the Angular CLI.

  3. Create a new Angular application.
    ng new my-app

    More information about creating a new Angular application.

    You are welcome to skip this step if you have already created an Angular application.

  4. Add the angular-auth-oidc-client library.
    ng add angular-auth-oidc-client

    Please enter the details below when prompted:

    • What flow to use? OIDC Code Flow PKCE using refresh tokens
    • Please enter your STS URL or Azure tenant id or Http config URL: https://identity.apetito.co.uk

    You may need to specify an explicit version of the angular-auth-oidc-client library to add if you are not using the latest compatible version of Angular.

  5. Add the necessary details to the auth config module (src → app → auth → auth-config.module.ts).
    export function configureAuth(oidcConfigService: OidcConfigService): () => Promise<any> {
      return () =>
        oidcConfigService.withConfig({
          stsServer: 'https://identity.apetito.co.uk',
          redirectUrl: window.location.origin,
          postLogoutRedirectUri: window.location.origin,
          clientId: '<insert client id here>',
          scope: 'openid profile offline_access Products.Read.All',
          responseType: 'code',
          silentRenew: true,
          useRefreshToken: true,
          renewTimeBeforeTokenExpiresInSeconds: 30,
          secureRoutes: ['https://data.apetito.co.uk'],
        });
    }

    The client ID can be found in the details of the application that you registered earlier.

  6. Call the check auth method in the app component (src → app → app.component.ts).
    import { OidcSecurityService } from 'angular-auth-oidc-client';
    constructor(private oidcSecurityService: OidcSecurityService) { }
    
    ngOnInit(): void {
      this.oidcSecurityService.checkAuth().subscribe();
    }
  7. Add the auth interceptor to the list of providers in the app module (src → app → app.module.ts).
    import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
    import { AuthInterceptor } from 'angular-auth-oidc-client';
    providers: [
      { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
    ]
  8. Add a product model (src → app → product.ts).
    export interface Product {
      code: string;
      name: string;
    }

    You may wish to add additional fields to the product model based on the response schema.

  9. Generate a product service (src → app → product.service.ts).
    ng generate service product
  10. Add a method to the product service (src → app → product.service.ts) to get a list of products.
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { Product } from './product';
    constructor(private http: HttpClient) { }
    
    get(): Observable<Product[]> {
      return this.http.get<Product[]>('https://data.apetito.co.uk/product/products');
    }
  11. Generate a products component (src → app → products).
    ng generate component products
  12. Update the products component (src → app → products → products.component.ts) to get a list of products.
    import { Observable } from 'rxjs';
    import { Product } from '../product';
    import { ProductService } from '../product.service';
    products$!: Observable<Product[]>
    
    constructor(private productService: ProductService) { }
    
    ngOnInit(): void {
      this.products$ = this.productService.get();
    }
  13. Update the products component (src → app → products → products.component.html) to render the list of products.
    <ul *ngIf="products$ | async as products; else loading">
      <li *ngFor="let product of products">{{product.name}}</li>
    </ul>
    
    <ng-template #loading>
      Loading...
    </ng-template>
  14. Add the products component (src → app → products) to the app routing module (src → app → app-routing.module.ts).
    import { AutoLoginGuard } from 'angular-auth-oidc-client';
    import { ProductsComponent } from './products/products.component';
    const routes: Routes = [
      { path: 'products', component: ProductsComponent, canActivate: [AutoLoginGuard] },
    ];
  15. Serve the application and navigate to the products page.
    npm run start
  16. You have now created a new Angular application that integrates with our product data.

    Explore our APIs to integrate your new Angular application with our other sources of data.

  1. Register a new web application with the openid, profile, and Products.Read.All scopes.
  2. Create a new ASP.NET Core web app project.
    dotnet new webapp --output aspnetcoreapp

    More information about creating a new ASP.NET Core application.

    You are welcome to skip this step if you have already created an ASP.NET Core application.

  3. Initialise and set the application's user secrets.
    dotnet user-secrets init
    dotnet user-secrets set "Authentication:Apetito:ClientId" "<insert client id here>"
    dotnet user-secrets set "Authentication:Apetito:ClientSecret" "<insert client secret here>"

    The client ID and client secret can be found in the details of the application that you registered earlier.

  4. Add the Microsoft.AspNetCore.Authentication.OpenIdConnect package.
    dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
  5. Add authentication to the application's services (Startup.cs → ConfigureServices).
    using Microsoft.AspNetCore.Authentication.Cookies;
    using Microsoft.AspNetCore.Authentication.OpenIdConnect;
    services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.Authority = "https://identity.apetito.co.uk";
        options.ClientId = Configuration["Authentication:Apetito:ClientId"];
        options.ClientSecret = Configuration["Authentication:Apetito:ClientSecret"];
        options.ResponseType = "code";
        options.Scope.Add("Products.Read.All");
        options.SaveTokens = true;
    });
  6. Add HTTP client to the application's services (Startup.cs → ConfigureServices).
    services.AddHttpClient();
  7. Configure the application to use authentication (Startup.cs → Configure).
    app.UseAuthentication();
    app.UseAuthorization();
  8. Add a product model (Product.cs).
    public class Product
    {
        public string Code { get; set; }
    
        public string Name { get; set; }
    }

    You may wish to add additional fields to the product model based on the response schema.

  9. Add a new products page (Pages → Products.cshtml).
    dotnet new page --name Products --namespace aspnetcoreapp.Pages --output Pages
  10. Add the authorize attribute to the products page model (Pages → Products.cshtml.cs).
    using Microsoft.AspNetCore.Authorization;
    [Authorize]
    public class ProductsModel : PageModel
    {
    }
  11. Inject the HTTP client factory into the products page model (Pages → Products.cshtml.cs).
    using System.Net.Http;
    public ProductsModel(IHttpClientFactory httpClientFactory)
    {
        HttpClientFactory = httpClientFactory;
    }
    
    private IHttpClientFactory HttpClientFactory { get; }
  12. Update the products page model (Pages → Products.cshtml.cs) to get a list of products.
    using System.Collections.Generic;
    using System.Net.Http.Json;
    public IEnumerable<Product> Products { get; set; }
    
    public async Task OnGetAsync()
    {
        using (var client = HttpClientFactory.CreateClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await HttpContext.GetTokenAsync("access_token"));
            Products = await client.GetFromJsonAsync<IEnumerable<Product>>("https://data.apetito.co.uk/product/products");
        }
    }
  13. Update the products page (Pages → Products.cshtml) to render the list of products.
    @page
    @model ProductsModel
    @{
        ViewData["Title"] = "Products";
    }
    
    <ul class="list-group">
        @foreach (var product in Model.Products)
        {
            <li class="list-group-item">@product.Name</li>
        }
    </ul>
  14. Add the products page to the navigation in the layout partial (Pages → Shared → _Layout.cshtml).
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="" asp-page="/Products">Products</a>
    </li>
  15. Run the application and navigate to the products page.
    dotnet run
  16. You have now created a new ASP.NET Core application that integrates with our product data.

    Explore our APIs to integrate your new ASP.NET Core application with our other sources of data.

  1. Register a new machine-to-machine application with the Products.Read.All scope.
  2. Open Microsoft Excel and create a new blank workbook.
  3. Launch the Power Query Editor (Data → Get Data → Launch Power Query Editor).
  4. Create a new Blank Query (Home → New Source → Other Sources → Blank Query).
  5. Open the Advanced Editor (Home → Advanced Editor).
  6. Obtain an access token and send an authorized request.
    let
        ClientId = "<insert client id here>",
        ClientSecret = "<insert client secret here>", // DO NOT DISTRIBUTE THIS WORKBOOK WITH THE CLIENT SECRET STORED IN PLAIN-TEXT!
    
        DiscoveryDocument = Json.Document(
            Web.Contents(
                "https://identity.apetito.co.uk/.well-known/openid-configuration"
            )
        ),
    
        AccessToken = Json.Document(
            Web.Contents(
                DiscoveryDocument[token_endpoint],
                [
                    Headers = [
                        #"Authorization" = "Basic " & Binary.ToText(Text.ToBinary(ClientId & ":" & ClientSecret), 0),
                        #"Content-Type" = "application/x-www-form-urlencoded"
                    ],
                    Content = Text.ToBinary("grant_type=client_credentials&scope=Products.Read.All")
                ]
            )
        ),
    
        Products = Json.Document(
            Web.Contents(
                "https://data.apetito.co.uk/product/products",
                [
                    Headers = [
                        #"Authorization" = "Bearer " & AccessToken[access_token]
                    ]
                ]
            )
        ),
    
        Source = Table.FromRecords(Products)
    in
        Source

    The client ID and client secret can be found in the details of the application that you registered earlier.

  7. Specify how to connect using the Edit Credentials prompt.
  8. Select anonymous access for both of the web contents.
  9. Close and Load the Power Query Editor (Home → Close and Load).
  10. You have now created a new Microsoft Excel workbook that integrates with our product data.

    Explore our APIs to integrate your new Microsoft Excel workbook with our other sources of data.

  1. Register a new machine-to-machine application with the Products.Read.All scope.
  2. Obtain an access token using your application's client credentials.
    $ClientId = "<insert client id here>"
    $ClientSecret = "<insert client secret here>" # DO NOT DISTRIBUTE THIS SCRIPT WITH THE CLIENT SECRET STORED IN PLAIN-TEXT!
    
    $Uri = "https://identity.apetito.co.uk/.well-known/openid-configuration"
    $DiscoveryDocument = Invoke-RestMethod -Method "Get" -Uri $Uri
    
    $Body = @{ grant_type = "client_credentials"; scope = "Products.Read.All" }
    $Headers = @{ Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("${ClientId}:${ClientSecret}")))" }
    $Uri = $DiscoveryDocument.token_endpoint
    $AccessToken = Invoke-RestMethod -Body $Body -Headers $Headers -Method "Post" -Uri $Uri

    The client ID and client secret can be found in the details of the application that you registered earlier.

  3. Send an authorized request to get a list of products.
    $Headers = @{ Authorization = "Bearer " + $AccessToken.access_token }
    $Uri = "https://data.apetito.co.uk/product/products"
    $Products = Invoke-RestMethod -Headers $Headers -Method "Get" -Uri $Uri
  4. You have now created a new PowerShell script that integrates with our product data.

    Explore our APIs to integrate your new PowerShell script with our other sources of data.

Our APIs are secured using the industry standard OpenID Connect protocol.

The discovery endpoint for apetito's identity platform can be found here.

Registering an Application

Before your application is able to obtain an access token, it needs to be registered in apetito's identity platform. You can register your application from your dashboard.

Obtaining an Access Token

To request an access token, applications obtain authorization from the user. This authorization is expressed in the form of a grant, which the application uses to request a token.

The client credentials grant can be used by machine-to-machine (confidential) applications without an end user.

Access Token Request

Please note that the client id and client secret should be Base64 encoded and provided in the authorization header.

POST /connect/token HTTP/1.1
Host: identity.apetito.co.uk
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
Access Token Response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "Bearer",
    "expires_in": 3600
}

The authorization code grant can be used by web (confidential) applications with an end user.

Authorization Request
GET /connect/authorize?response_type=code&client_id=s6BhdRkqt3&state=…&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcallback HTTP/1.1
Host: identity.apetito.co.uk
Authorization Response
HTTP/1.1 302 Found
Location: https://client.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=…
Access Token Request

Please note that the client id and client secret should be Base64 encoded and provided in the authorization header.

POST /connect/token HTTP/1.1
Host: identity.apetito.co.uk
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcallback
Access Token Response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}

The authorization code grant can be used by single-page (public) applications with an end user.

Authorization Request
GET /connect/authorize?response_type=code&client_id=s6BhdRkqt3&state=…&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcallback&code_challenge=…&code_challenge_method=S256 HTTP/1.1
Host: identity.apetito.co.uk
Authorization Response
HTTP/1.1 302 Found
Location: https://client.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=…
Access Token Request

Please note that the client id should be provided in the request body.

POST /connect/token HTTP/1.1
Host: identity.apetito.co.uk
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcallback&client_id=s6BhdRkqt3&code_verifier=…
Access Token Response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}

The authorization code grant can be used by mobile and desktop (public) applications with an end user.

Authorization Request
GET /connect/authorize?response_type=code&client_id=s6BhdRkqt3&state=…&redirect_uri=com%2Eexample%2Eclient%3A%2F%2Fcallback&code_challenge=…&code_challenge_method=S256 HTTP/1.1
Host: identity.apetito.co.uk
Authorization Response
HTTP/1.1 302 Found
Location: com.example.client://callback?code=SplxlOBeZQQYbYS6WxSbIA&state=…
Access Token Request

Please note that the client id should be provided in the request body.

POST /connect/token HTTP/1.1
Host: identity.apetito.co.uk
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=com%2Eexample%2Eclient%3A%2F%2Fcallback&client_id=s6BhdRkqt3&code_verifier=…
Access Token Response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}