diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/sites/dto/SiteId.java b/ccm-core/src/main/java/org/libreccm/api/admin/sites/dto/SiteId.java
new file mode 100644
index 000000000..69af10423
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/sites/dto/SiteId.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.sites.dto;
+
+import org.libreccm.sites.Site;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class SiteId {
+
+ private long siteId;
+
+ private String uuid;
+
+ private String domainOfSite;
+
+
+ public SiteId() {
+ super();
+ }
+
+ public SiteId(final Site site) {
+ siteId = site.getObjectId();
+ uuid = site.getUuid();
+ domainOfSite = site.getDomainOfSite();
+ }
+
+ public long getSiteId() {
+ return siteId;
+ }
+
+ public void setSiteId(long siteId) {
+ this.siteId = siteId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getDomainOfSite() {
+ return domainOfSite;
+ }
+
+ public void setDomainOfSite(String domainOfSite) {
+ this.domainOfSite = domainOfSite;
+ }
+
+
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/web/CcmApplicationsApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/web/CcmApplicationsApi.java
new file mode 100644
index 000000000..1aeed0def
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/web/CcmApplicationsApi.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.web;
+
+import org.libreccm.api.admin.categorization.dto.DomainOwnershipData;
+import org.libreccm.api.admin.web.dto.CcmApplicationDto;
+import org.libreccm.api.dto.ListView;
+import org.libreccm.core.CoreConstants;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.RequiresPrivilege;
+
+import javax.enterprise.context.RequestScoped;
+import javax.transaction.Transactional;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Path("/applications/")
+public class CcmApplicationsApi {
+
+ @GET
+ @Path("/")
+ @Produces(MediaType.APPLICATION_JSON)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public ListView getAllApplications(
+ @QueryParam("site-aware-only") @DefaultValue("false")
+ final boolean siteAwareOnly,
+ @QueryParam("limit") @DefaultValue("20") final int limit,
+ @QueryParam("offset") @DefaultValue("0") final int offset
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @GET
+ @Path("/{appIdentifier}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public CcmApplicationDto getApplication(
+ @PathParam("appIdentifier") final String appIdentifier
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @POST
+ @Path("/")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Response createApplication(final CcmApplicationDto applicationData) {
+ throw new UnsupportedOperationException();
+ }
+
+ @PUT
+ @Path("/{appIdentifier}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Response updateApplication(
+ @PathParam("appIdentifier") final String appIdentifier,
+ final CcmApplicationDto applicationData
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @DELETE
+ @Path("/{appIdentifier}")
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Response deleteApplication(
+ @PathParam("appIdentifier") final String appIdentifier
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @GET
+ @Path("/{appIdentifier}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public ListView getDomains(
+ @PathParam("appIdentifier") final String appIdentifier,
+ @QueryParam("limit") @DefaultValue("20") final int limit,
+ @QueryParam("offset") @DefaultValue("0") final int offset
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @PUT
+ @Path("/{appIdentifier}/domains/{domainIdentifier}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Response addOwner(
+ @PathParam("ownerIdentifier") final String appIdentifier,
+ @PathParam("domainIdentifier") final String domainIdentifier
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @DELETE
+ @Path("/{appIdentifier}/domains/{domainIdentifier}")
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Response removeOwner(
+ @PathParam("appIdentifier") final String ownerIdentifierParam,
+ @PathParam("domainIdentifier") final String domainIdentifierParam
+ ) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/web/dto/CcmApplicationDto.java b/ccm-core/src/main/java/org/libreccm/api/admin/web/dto/CcmApplicationDto.java
new file mode 100644
index 000000000..52c6089d0
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/web/dto/CcmApplicationDto.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.web.dto;
+
+import org.libreccm.api.admin.categorization.dto.DomainOwnershipData;
+import org.libreccm.api.admin.sites.dto.SiteId;
+import org.libreccm.l10n.LocalizedString;
+import org.libreccm.sites.SiteAwareApplication;
+import org.libreccm.web.CcmApplication;
+
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class CcmApplicationDto {
+
+ private long applicationId;
+
+ private String uuid;
+
+ private LocalizedString title;
+
+ private LocalizedString description;
+
+ private String created;
+
+ private String applicationType;
+
+ private String primaryUrl;
+
+ private List domains;
+
+ private boolean siteAware;
+
+ private SiteId site;
+
+ public CcmApplicationDto() {
+ super();
+ }
+
+ public CcmApplicationDto(final CcmApplication application) {
+ this();
+
+ Objects.requireNonNull(
+ application, "Can't create a CcmApplicationDto from null."
+ );
+
+ applicationId = application.getObjectId();
+ uuid = application.getUuid();
+ title = application.getTitle();
+ description = application.getDescription();
+ created = DateTimeFormatter.ISO_DATE_TIME.format(
+ application.getCreated().toInstant()
+ );
+ applicationType = application.getApplicationType();
+ primaryUrl = application.getPrimaryUrl();
+ domains = application
+ .getDomains()
+ .stream()
+ .map(DomainOwnershipData::new)
+ .collect(Collectors.toList());
+ siteAware = false;
+ }
+
+ public CcmApplicationDto(final SiteAwareApplication application) {
+ this((CcmApplication) application);
+ siteAware = true;
+ site = new SiteId(application.getSite());
+ }
+
+ public long getApplicationId() {
+ return applicationId;
+ }
+
+ public void setApplicationId(final long applicationId) {
+ this.applicationId = applicationId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public LocalizedString getTitle() {
+ return title;
+ }
+
+ public void setTitle(final LocalizedString title) {
+ this.title = title;
+ }
+
+ public LocalizedString getDescription() {
+ return description;
+ }
+
+ public void setDescription(final LocalizedString description) {
+ this.description = description;
+ }
+
+ public String getCreated() {
+ return created;
+ }
+
+ public void setCreated(final String created) {
+ this.created = created;
+ }
+
+ public String getApplicationType() {
+ return applicationType;
+ }
+
+ public void setApplicationType(final String applicationType) {
+ this.applicationType = applicationType;
+ }
+
+ public String getPrimaryUrl() {
+ return primaryUrl;
+ }
+
+ public void setPrimaryUrl(final String primaryUrl) {
+ this.primaryUrl = primaryUrl;
+ }
+
+ public List getDomains() {
+ return new ArrayList<>(domains);
+ }
+
+ public void setDomains(final List domains) {
+ this.domains = new ArrayList<>(domains);
+ }
+
+ public boolean isSiteAware() {
+ return siteAware;
+ }
+
+ public void setSiteAware(boolean siteAware) {
+ this.siteAware = siteAware;
+ }
+
+ public SiteId getSite() {
+ return site;
+ }
+
+ public void setSite(SiteId site) {
+ this.site = site;
+ }
+
+}