# Confused about internal services

**URL:** <https://community.traefik.io/t/confused-about-internal-services/24376>\
**Category:** Traefik v3 (latest)\
**Tags:** rest-api, dashboard-api\
**Created:** [September 9, 2024, 7:18pm UTC](https://community.traefik.io/t/confused-about-internal-services/24376 "2024-09-09T19:18:15Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pzdrs](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/pzdrs/32/9289_2.png) [@Pzdrs](https://community.traefik.io/u/Pzdrs)\
**Post date:** [September 9, 2024, 7:18pm UTC](https://community.traefik.io/t/confused-about-internal-services/24376/1 "2024-09-09T19:18:15Z")

</div>

Hello,  
when setting up a new Traefik instance (dashboard access), I've always just pasted in what worked the first time and haven't given it much thought (i.e. the following router).

```auto
traefik-dashboard:
      entryPoints: ["https"]
      rule: "Host(`traefik.domain.com`)"
      tls: {}
      service: api@internal

```

Now I'm wondering, though, there are two internal services that confuse me - the **api@internal** and **dashboard@internal**. My thought process is that the API service would be used for the HTTP API and the dashboard one to display the dashboard. When I change out the api@internal for dashboard@internal, I get the application but no data. The AJAX requests it's making are directed to the current URL with the API endpoint appended, but the API is no longer being served at /api.

So, let's say I wanted to have the dashboard at [traefik.domain.com](http://traefik.domain.com) and the API at [api.traefik.domain.com](http://api.traefik.domain.com) (usage -\> [api.traefik.domain.com/entrypoints](http://api.traefik.domain.com/entrypoints)). How would one achieve that?

Note that I never actually used the API and I don't think I ever will. This is more of a hypothetical question as I want to understand Traefik beyond an "I'm able to add a router" knowledge.

Thank you

---

<div class="post-metadata">

**Author:** ![bluepuma77](https://avatars.discourse-cdn.com/v4/letter/b/a9adbd/32.png) [@bluepuma77](https://community.traefik.io/u/bluepuma77)\
**Post date:** [September 10, 2024, 6:17am UTC](https://community.traefik.io/t/confused-about-internal-services/24376/2 "2024-09-10T06:17:31Z")

</div>

You are probably the first person going down that path 😉

Usually api and dashboard go together, as in [doc](https://doc.traefik.io/traefik/operations/dashboard/#dashboard-router-rule):

```auto

# Dynamic Configuration
labels:
  - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
  - "traefik.http.routers.dashboard.service=api@internal"
  - "traefik.http.routers.dashboard.middlewares=auth"
  - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"

```

There is no way to even set a different path for `/dashboard`, so I doubt there will be a way to tell it to use a different host for api requests.

---

<div class="post-metadata">

**Author:** ![Pzdrs](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/pzdrs/32/9289_2.png) [@Pzdrs](https://community.traefik.io/u/Pzdrs)\
**Post date:** [September 10, 2024, 6:33am UTC](https://community.traefik.io/t/confused-about-internal-services/24376/3 "2024-09-10T06:33:24Z")

</div>

Alright, I’m glad I didn’t miss anything. I was just wondering why they’re split and I only ever see people use the api not the dashboard service.

---

<div class="post-metadata">

**Author:** ![hafio](https://avatars.discourse-cdn.com/v4/letter/h/278dde/32.png) [@hafio](https://community.traefik.io/u/hafio)\
**Post date:** [September 14, 2025, 3:21am UTC](https://community.traefik.io/t/confused-about-internal-services/24376/4 "2025-09-14T03:21:44Z")

</div>

You can by using middlewares to redirect and perform path manipulation:

```auto
http:
  routers:
    traefik-api:
      rule: Host(`api.example.com`)
      entryPoints:
        - websecure
      middlewares:
        - allow-dashboard-cors
        - strip-api
        - add-api
      service: api@internal
    traefik-dashboard-redirect-api:
      rule: Host(`dashboard.example.com`) && PathPrefix(`/api/`)
      entryPoints:
        - websecure
      middlewares:
        - redirect-dashboard-to-api
      service: noop@internal
    traefik-dashboard:
      rule: Host(`dashboard.example.com`)
      entryPoints:
        - websecure
      middlewares:
        - auth
        - strip-dashboard
        - add-dashboard
      service: api@internal

  middlewares:
    auth:
      basicAuth:
        users:
          - "hafio:$2y$05$U6NESdpShx529Ao1bAJI/.x42WGE5ZFNBYp2PICrEGsDAC2d86kFK"
    allow-dashboard-cors:
      headers:
        accessControlAllowOriginList:
        - https://dashboard.example.com
    redirect-dashboard-to-api:
      redirectRegex:
        regex: "^https://dashboard\\.example\\.com/api/(.*)"
        replacement: "https://api.example.com/$1"
        permanent: true
    add-api:
      addPrefix:
        prefix: "/api"
    add-dashboard:
      addPrefix:
        prefix: "/dashboard"
    strip-api:
      stripPrefix:
        prefixes: "/api"
    strip-dashboard:
      stripPrefix:
        prefixes: "/dashboard"

```

[dashboard.example.com/api](http://dashboard.example.com/api) redirects to [api.example.com](http://api.example.com) - i did not do the reverse since the entry point is usually [dashboard.example.com](http://dashboard.example.com)
