# ACDA (App Content Delivery API)

ACDA (App Content Delivery API) is a read-only API that delivers published *Content* and *Media* to members who have signed up for your product, that is to *ServiceUser*s. Once the team running a *Space* publishes content, members read that published data through ACDA. Think of it as the *ServiceUser* version of what CDA does, performing the same role of delivering published content under a member identity instead of to public visitors. ACDA has only read (GET) endpoints; creating, updating, and deleting belong to [ACMA](/api/reference/acma.md).

ACDA calls use a Bearer token issued by *ServiceLogin*. This token is valid only on ACMA and ACDA and cannot be used on CMA or CDA (for the token issuance flow, see the [Auth API](/api/reference/auth-api.md)).
## Differences from CDA {#differences-from-cda}

ACDA's response shape is the same as CDA's. It delivers only a snapshot of the published data (`sys` carries only `revision`, the version at the time of publish, with no `version`, `status`, or `publish`), and it resolves values by `locale` at read time. **What differs from CDA is the read scope and the identity.**

- **Per-member read scope:** With CDA, anyone calling with a single DeliveryAccessToken sees the same published set. ACDA returns only what is allowed for the calling *ServiceUser*, and what is allowed is determined by that member's *ServiceUserRole* and their assignments. The identity differs too: CDA is called with a DeliveryAccessToken, ACDA with the member token issued by *ServiceLogin*.

How the `locale` query parameter chooses the language to receive is also the same as CDA. Given a code such as `locale=ko-KR`, `fields` comes back as a single value for that locale (empty or `null` if there is no value and the *Fallback* does not reach one); omitted, it returns the same way for the *Space*'s default *Locale*; and given `locale=*`, it returns the map holding all locale values as is. In the first two cases, where a single language is returned, the response carries an `x-weegloo-locale` header that reports the locale actually used (it is absent when `locale=*`).

## Resource structure {#resource-structure}

The following is the form in which ACDA delivers one "Product" *Content* from a demo *Space*. It is the result of reading with `locale=en-US`, and each value in `fields` is held as a single value resolved to `en-US`.

```json
{
  "sys": {
    "id": "3trmXRM3RqbgSnifyg7PBUM8Ds0Xvw",
    "type": "Content",
    "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
    "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
    "createdAt": "2026-06-17T16:58:56.660Z",
    "updatedAt": "2026-06-18T01:46:58.358Z",
    "revision": 3
  },
  "fields": {
    "productName": "Stainless Tumbler 500ml",
    "price": 18000,
    "description": "Double-wall vacuum insulation keeps drinks hot or cold for hours. A roomy 500ml."
  }
}
```

Key properties:

- `sys.id`: The unique identifier of the *Content*. It goes into `{contentId}` in the single-read path.
- `sys.type`: The resource kind. For a *Content* this is always `"Content"`.
- `sys.space`: A reference pointing to the *Space* this *Content* belongs to.
- `sys.contentType`: A reference pointing to the *Content Type* this *Content* follows.
- `sys.revision`: The version at the time of publish. Each publish records the version at that moment here. Because ACDA does not carry the management fields `version`, `status`, or `publish`, `revision` is the one value that points to the published version.
- `sys.createdBy`, `sys.updatedBy`: Included only when the *Content Type*'s `publishWithAuthor` is turned on, pointing to the author and the last editor. The example above has this option turned off, so the two keys are omitted.
- `fields`: Holds each field's value in the shape `{ apiName: value }`. Unlike the locale map of CMA and ACMA (`{ apiName: { locale: value } }`), ACDA holds only a single value resolved to the requested `locale`. In the example above the representative photo `photo` is omitted because there is no value for that locale.

*Media* comes back in the same published delivery form, carrying only `revision` in `sys` and not `version`, `status`, or `publish`. *Media* always omits author information (`createdBy` and `updatedBy`). A *Media*'s `fields.file` also comes back as a single object resolved to the requested locale.

## API {#api}

All three endpoints are reads (GET), and the `locale` query parameter chooses the language to receive (a code for that locale, omitted for the default *Locale*, `*` for the full map; see above).

```api-endpoint
{
  "title": "List published Content",
  "method": "GET",
  "path": "/spaces/{spaceId}/content-types/{contentTypeId}/contents",
  "description": "Lists the published Content under one Content Type, page by page. The target is only the data allowed for the calling ServiceUser, and fields come back as a single value resolved to locale.",
  "responseStatus": 200,
  "baseUrl": "https://acda.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "contentTypeId": { "type": "string", "description": "The sys.id of the Content Type", "required": true }
  },
  "queryParameterSchema": {
    "locale": { "type": "string", "description": "Language to receive. A code (e.g. en-US) returns values for that locale, omitting it uses the default Locale, and * returns the full locale map." },
    "limit": { "type": "integer", "description": "Number of items to return per page (1-100)", "default": 15 },
    "skip": { "type": "integer", "description": "Number of items to skip", "default": 0 },
    "next": { "type": "string", "description": "Next page cursor (the value obtained from links.next of the previous response)" },
    "prev": { "type": "string", "description": "Previous page cursor (the value obtained from links.prev of the previous response)" },
    "order": { "type": "string", "description": "Sort criteria. Multiple sorts separated by commas (for example, sys.createdAt,sys.id)", "default": "sys.createdAt,sys.id" },
    "include": { "type": "integer", "description": "Level of related resources to include. 0=default, 1=related resources, 2=nested relations, 3=all", "default": 0 },
    "select": { "type": "string", "description": "Fields to include (sys.id,sys.createdAt) or exclude (-sys.id). Do not mix include and exclude." }
  },
  "additionalQueryParams": true,
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (ACDA authentication, issued by ServiceLogin)" }
  },
  "responseExample": {
    "sys": { "type": "TotalPageResponse" },
    "limit": 15,
    "totalCount": 1,
    "items": [
      {
        "sys": {
          "id": "3trmXRM3RqbgSnifyg7PBUM8Ds0Xvw",
          "type": "Content",
          "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
          "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
          "createdAt": "2026-06-17T16:58:56.660Z",
          "updatedAt": "2026-06-18T01:46:58.358Z",
          "revision": 3
        },
        "fields": {
          "productName": "Stainless Tumbler 500ml",
          "price": 18000,
          "description": "Double-wall vacuum insulation keeps drinks hot or cold for hours. A roomy 500ml."
        }
      }
    ],
    "links": { "self": "/v1/spaces/tcq4V2Xb/content-types/3trmXRM3RqbgSnifyg7PAmlxvX4fGY/contents?locale=en-US" }
  }
}
```

```api-endpoint
{
  "title": "Read a single published Content",
  "method": "GET",
  "path": "/spaces/{spaceId}/content-types/{contentTypeId}/contents/{contentId}",
  "description": "Reads one published Content by sys.id. fields come back as a single value resolved to locale.",
  "responseStatus": 200,
  "baseUrl": "https://acda.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "contentTypeId": { "type": "string", "description": "The sys.id of the Content Type", "required": true },
    "contentId": { "type": "string", "description": "The sys.id of the Content", "required": true }
  },
  "queryParameterSchema": {
    "locale": { "type": "string", "description": "Language to receive. A code (e.g. en-US) returns values for that locale, omitting it uses the default Locale, and * returns the full locale map." },
    "include": { "type": "integer", "description": "Level of related resources to include. 0=default, 1=related resources, 2=nested relations, 3=all", "default": 0 }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (ACDA authentication, issued by ServiceLogin)" }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PBUM8Ds0Xvw",
      "type": "Content",
      "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
      "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
      "createdAt": "2026-06-17T16:58:56.660Z",
      "updatedAt": "2026-06-18T01:46:58.358Z",
      "revision": 3
    },
    "fields": {
      "productName": "Stainless Tumbler 500ml",
      "price": 18000,
      "description": "Double-wall vacuum insulation keeps drinks hot or cold for hours. A roomy 500ml."
    }
  }
}
```

```api-endpoint
{
  "title": "Read a single published Media",
  "method": "GET",
  "path": "/spaces/{spaceId}/medias/{mediaId}",
  "description": "Reads one published Media by sys.id. fields.file comes back as a single object resolved to locale.",
  "responseStatus": 200,
  "baseUrl": "https://acda.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "mediaId": { "type": "string", "description": "The sys.id of the Media", "required": true }
  },
  "queryParameterSchema": {
    "locale": { "type": "string", "description": "Language to receive. A code (e.g. en-US) returns values for that locale, omitting it uses the default Locale, and * returns the full locale map." },
    "include": { "type": "integer", "description": "Level of related resources to include. 0=default, 1=related resources, 2=nested relations, 3=all", "default": 0 }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (ACDA authentication, issued by ServiceLogin)" }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PBe7ehkOn8e",
      "type": "Media",
      "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
      "createdAt": "2026-06-17T17:07:13.154Z",
      "updatedAt": "2026-06-17T17:07:13.400Z",
      "revision": 1
    },
    "fields": {
      "title": "Stainless Tumbler 500ml front shot",
      "description": "Front product shot of the tumbler on a white background.",
      "file": {
        "fileName": "tumbler.png",
        "contentType": "image/png",
        "mimeGroups": ["Image"],
        "url": "https://weegloo-media.com/medias/tcq4V2Xb/n8e/3trmXRM3RqbgSnifyg7PBe7ehkOn8e/en-US/1/tumbler.png",
        "detail": { "size": 50847, "image": { "width": 900, "height": 900 } }
      }
    }
  }
}
```

## Related documents {#related-documents}

- [ACMA](/api/reference/acma.md): The management API where members create and edit their own content.
- [Auth API](/api/reference/auth-api.md): Issuing the token used in ACDA calls.
- [ServiceUser login (concept)](/getting-started/core-concepts/service-users/service-login.md): Configuring ServiceLogin, ServiceUserRole, and assignments.
