killbill-uncached

Changes

jaxrs/pom.xml 8(+8 -0)

pom.xml 2(+1 -1)

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
index a0c5599..357cef0 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
@@ -92,16 +92,22 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
             assertEquals(e.getCode(), ErrorCode.CAT_PLAN_NOT_FOUND.getCode());
         }
 
+
+        final DefaultEntitlement bpEntitlement2 =
+                createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey2", "Bazooka",
+                                                           ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
+        assertNotNull(bpEntitlement2);
+
+
         // Move out a month and verify 'Pistol' plan continue working as expected.
         busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
         clock.addMonths(1);
         assertListenerStatus();
 
+
         final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
-        assertEquals(invoices.size(), 3);
-        for (final Invoice invoice : invoices) {
-            assertEquals(invoice.getInvoiceItems().get(0).getPlanName(), "pistol-monthly");
-        }
+        assertEquals(invoices.size(), 4);
+
     }
 
     // Flaky, see https://github.com/killbill/killbill/issues/860
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
index 0357f98..049f602 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
@@ -409,6 +409,8 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
         // Account in PDT
         final AccountData accountData = new MockAccountBuilder().currency(Currency.USD)
                                                                 .timeZone(timeZone)
+                                                                // Fixed reference time, regardless of current DST
+                                                                .referenceTime(clock.getUTCNow())
                                                                 .build();
 
         final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
diff --git a/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v1.xml b/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v1.xml
index 5a977b6..9cd2a82 100644
--- a/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v1.xml
+++ b/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v1.xml
@@ -91,6 +91,11 @@
                 <alignment>START_OF_BUNDLE</alignment>
             </createAlignmentCase>
         </createAlignment>
+        <billingAlignment>
+            <billingAlignmentCase>
+                <alignment>BUNDLE</alignment>
+            </billingAlignmentCase>
+        </billingAlignment>
         <priceList>
             <priceListCase>
                 <fromPriceList>SpecialDiscount</fromPriceList>
diff --git a/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v2.xml b/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v2.xml
index c575b09..d9fe488 100644
--- a/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v2.xml
+++ b/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v2.xml
@@ -48,6 +48,9 @@
                 </limit>
             </limits>
         </product>
+        <product name="Bazooka">
+            <category>BASE</category>
+        </product>
         <product name="Laser-Scope">
             <category>ADD_ON</category>
         </product>
@@ -91,6 +94,11 @@
                 <alignment>START_OF_BUNDLE</alignment>
             </createAlignmentCase>
         </createAlignment>
+        <billingAlignment>
+            <billingAlignmentCase>
+                <alignment>BUNDLE</alignment>
+            </billingAlignmentCase>
+        </billingAlignment>
         <priceList>
             <priceListCase>
                 <fromPriceList>SpecialDiscount</fromPriceList>
@@ -297,6 +305,35 @@
                 </recurring>
             </finalPhase>
         </plan>
+        <plan name="bazooka-monthly">
+            <product>Bazooka</product>
+            <initialPhases>
+            </initialPhases>
+            <finalPhase type="EVERGREEN">
+                <duration>
+                    <unit>UNLIMITED</unit>
+                    <number>-1</number>
+                </duration>
+                <recurring>
+                    <billingPeriod>MONTHLY</billingPeriod>
+                    <recurringPrice>
+                        <price>
+                            <currency>USD</currency>
+                            <value>500.00</value>
+                        </price>
+                        <price>
+                            <currency>EUR</currency>
+                            <value>300.00</value>
+                        </price>
+                        <price>
+                            <currency>GBP</currency>
+                            <value>300.00</value>
+                        </price>
+                    </recurringPrice>
+                </recurring>
+            </finalPhase>
+        </plan>
+
     </plans>
     <priceLists>
         <defaultPriceList name="DEFAULT">
@@ -305,6 +342,7 @@
                 <plan>shotgun-annual</plan>
                 <plan>laser-scope-monthly</plan>
                 <plan>extra-ammo-monthly</plan>
+                <plan>bazooka-monthly</plan>
             </plans>
         </defaultPriceList>
         <childPriceList name="SpecialDiscount">
diff --git a/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v3.xml b/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v3.xml
index 63acb70..8c7a4ee 100644
--- a/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v3.xml
+++ b/beatrix/src/test/resources/retiredCatalogs/WeaponsHireSmall-v3.xml
@@ -89,6 +89,11 @@
                 <alignment>START_OF_BUNDLE</alignment>
             </createAlignmentCase>
         </createAlignment>
+        <billingAlignment>
+            <billingAlignmentCase>
+                <alignment>BUNDLE</alignment>
+            </billingAlignmentCase>
+        </billingAlignment>
     </rules>
 
     <plans>

jaxrs/pom.xml 8(+8 -0)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index f0a870a..4f27ef5 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -63,6 +63,14 @@
             <artifactId>swagger-annotations</artifactId>
         </dependency>
         <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-jaxrs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-models</artifactId>
+        </dependency>
+        <dependency>
             <groupId>javax.inject</groupId>
             <artifactId>javax.inject</artifactId>
             <scope>provided</scope>
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountEmailJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountEmailJson.java
index 4375643..ca1afdb 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountEmailJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountEmailJson.java
@@ -23,22 +23,24 @@ import org.killbill.billing.account.api.AccountEmail;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+
+@ApiModel(value="AccountEmail")
 public class AccountEmailJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
+    private final UUID accountId;
     @ApiModelProperty(required = true)
     private final String email;
 
     @JsonCreator
-    public AccountEmailJson(@JsonProperty("accountId") final String accountId, @JsonProperty("email") final String email) {
+    public AccountEmailJson(@JsonProperty("accountId") final UUID accountId, @JsonProperty("email") final String email) {
         this.accountId = accountId;
         this.email = email;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
@@ -51,7 +53,7 @@ public class AccountEmailJson extends JsonBase {
         return new AccountEmail() {
             @Override
             public UUID getAccountId() {
-                return UUID.fromString(accountId);
+                return accountId;
             }
 
             @Override
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java
index d9b0043..8f55507 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountJson.java
@@ -35,12 +35,13 @@ import org.killbill.billing.util.audit.AccountAuditLogs;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Strings;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Account")
 public class AccountJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
+    private final UUID accountId;
     private final String externalKey;
     private final BigDecimal accountCBA;
     private final BigDecimal accountBalance;
@@ -49,11 +50,9 @@ public class AccountJson extends JsonBase {
     private final String email;
     private final Integer billCycleDayLocal;
     private final String currency;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String parentAccountId;
+    private final UUID parentAccountId;
     private final Boolean isPaymentDelegatedToParent;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String paymentMethodId;
+    private final UUID paymentMethodId;
     private final DateTime referenceTime;
     private final String timeZone;
     private final String address1;
@@ -73,16 +72,16 @@ public class AccountJson extends JsonBase {
         super(toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForAccount()));
         this.accountCBA = accountCBA;
         this.accountBalance = accountBalance;
-        this.accountId = account.getId().toString();
+        this.accountId = account.getId();
         this.externalKey = account.getExternalKey();
         this.name = account.getName();
         this.firstNameLength = account.getFirstNameLength();
         this.email = account.getEmail();
         this.billCycleDayLocal = account.getBillCycleDayLocal();
         this.currency = account.getCurrency() != null ? account.getCurrency().toString() : null;
-        this.parentAccountId = account.getParentAccountId() != null ? account.getParentAccountId().toString() : null;
+        this.parentAccountId = account.getParentAccountId();
         this.isPaymentDelegatedToParent = account.isPaymentDelegatedToParent();
-        this.paymentMethodId = account.getPaymentMethodId() != null ? account.getPaymentMethodId().toString() : null;
+        this.paymentMethodId = account.getPaymentMethodId();
         this.referenceTime = account.getReferenceTime();
         this.timeZone = account.getTimeZone() != null ? account.getTimeZone().toString() : null;
         this.address1 = account.getAddress1();
@@ -100,16 +99,16 @@ public class AccountJson extends JsonBase {
     }
 
     @JsonCreator
-    public AccountJson(@JsonProperty("accountId") final String accountId,
+    public AccountJson(@JsonProperty("accountId") final UUID accountId,
                        @JsonProperty("name") final String name,
                        @JsonProperty("firstNameLength") final Integer firstNameLength,
                        @JsonProperty("externalKey") final String externalKey,
                        @JsonProperty("email") final String email,
                        @JsonProperty("billCycleDayLocal") final Integer billCycleDayLocal,
                        @JsonProperty("currency") final String currency,
-                       @JsonProperty("parentAccountId") final String parentAccountId,
+                       @JsonProperty("parentAccountId") final UUID parentAccountId,
                        @JsonProperty("isPaymentDelegatedToParent") final Boolean isPaymentDelegatedToParent,
-                       @JsonProperty("paymentMethodId") final String paymentMethodId,
+                       @JsonProperty("paymentMethodId") final UUID paymentMethodId,
                        @JsonProperty("referenceTime") final DateTime referenceTime,
                        @JsonProperty("timeZone") final String timeZone,
                        @JsonProperty("address1") final String address1,
@@ -205,11 +204,7 @@ public class AccountJson extends JsonBase {
 
             @Override
             public UUID getPaymentMethodId() {
-                if (Strings.emptyToNull(paymentMethodId) == null) {
-                    return null;
-                } else {
-                    return UUID.fromString(paymentMethodId);
-                }
+                return paymentMethodId;
             }
 
             @Override
@@ -279,11 +274,7 @@ public class AccountJson extends JsonBase {
 
             @Override
             public UUID getParentAccountId() {
-                if (Strings.emptyToNull(parentAccountId) == null) {
-                    return null;
-                } else {
-                    return UUID.fromString(parentAccountId);
-                }
+                return parentAccountId;
             }
 
             @Override
@@ -330,7 +321,7 @@ public class AccountJson extends JsonBase {
         return accountBalance;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
@@ -362,7 +353,7 @@ public class AccountJson extends JsonBase {
         return currency;
     }
 
-    public String getParentAccountId() {
+    public UUID getParentAccountId() {
         return parentAccountId;
     }
 
@@ -371,7 +362,7 @@ public class AccountJson extends JsonBase {
         return isPaymentDelegatedToParent;
     }
 
-    public String getPaymentMethodId() {
+    public UUID getPaymentMethodId() {
         return paymentMethodId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java
index 0cb8603..b3c5233 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AccountTimelineJson.java
@@ -39,7 +39,9 @@ import org.killbill.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="AccountTimeline")
 public class AccountTimelineJson {
 
     private final AccountJson account;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AdminPaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AdminPaymentJson.java
index 3ed676e..2dc7170 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AdminPaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AdminPaymentJson.java
@@ -19,7 +19,9 @@ package org.killbill.billing.jaxrs.json;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="AdminPayment")
 public class AdminPaymentJson {
 
     private final String lastSuccessPaymentState;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AuditLogJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AuditLogJson.java
index 05813b1..0352df3 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AuditLogJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/AuditLogJson.java
@@ -22,8 +22,10 @@ import org.killbill.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="AuditLog")
 public class AuditLogJson {
 
     private final String changeType;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java
index 181fa6d..2dd9324 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BillingExceptionJson.java
@@ -27,8 +27,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import io.swagger.annotations.ApiModel;
 
 // Doesn't extend JsonBase (no audit logs)
+@ApiModel(value="BillingException")
 public class BillingExceptionJson {
 
     private final String className;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockingStateJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockingStateJson.java
index f594266..1482cf2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockingStateJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockingStateJson.java
@@ -30,12 +30,13 @@ import org.killbill.billing.util.audit.AccountAuditLogs;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="BlockingState")
 public class BlockingStateJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String blockedId;
+    private final UUID blockedId;
     private final String stateName;
     private final String service;
     private final Boolean blockChange;
@@ -45,7 +46,7 @@ public class BlockingStateJson extends JsonBase {
     private final BlockingStateType type;
 
     @JsonCreator
-    public BlockingStateJson(@JsonProperty("blockedId") final String blockedId,
+    public BlockingStateJson(@JsonProperty("blockedId") final UUID blockedId,
                              @JsonProperty("stateName") final String stateName,
                              @JsonProperty("service") final String service,
                              @JsonProperty("blockChange") final Boolean blockChange,
@@ -66,7 +67,7 @@ public class BlockingStateJson extends JsonBase {
     }
 
     public BlockingStateJson(final BlockingState input, final AccountAuditLogs accountAuditLogs) {
-        this(input.getBlockedId().toString(),
+        this(input.getBlockedId(),
              input.getStateName(),
              input.getService(),
              input.isBlockChange(),
@@ -78,7 +79,7 @@ public class BlockingStateJson extends JsonBase {
     }
 
 
-    public String getBlockedId() {
+    public UUID getBlockedId() {
         return blockedId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockPriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockPriceOverrideJson.java
index e24a727..660fd04 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockPriceOverrideJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BlockPriceOverrideJson.java
@@ -23,7 +23,9 @@ import javax.annotation.Nullable;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="BlockPriceOverride")
 public class BlockPriceOverrideJson {
 
     private String unitName;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java
index ebc5d70..78927d3 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleJson.java
@@ -20,6 +20,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -31,21 +32,22 @@ import org.killbill.billing.util.audit.AccountAuditLogs;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Bundle")
 public class BundleJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID", required = true)
-    private final String accountId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String bundleId;
+    @ApiModelProperty(required = true)
+    private final UUID accountId;
+    private final UUID bundleId;
     private final String externalKey;
     private final List<SubscriptionJson> subscriptions;
     private final BundleTimelineJson timeline;
 
     @JsonCreator
-    public BundleJson(@JsonProperty("accountId") @Nullable final String accountId,
-                      @JsonProperty("bundleId") @Nullable final String bundleId,
+    public BundleJson(@JsonProperty("accountId") @Nullable final UUID accountId,
+                      @JsonProperty("bundleId") @Nullable final UUID bundleId,
                       @JsonProperty("externalKey") @Nullable final String externalKey,
                       @JsonProperty("subscriptions") @Nullable final List<SubscriptionJson> subscriptions,
                       @JsonProperty("timeline") @Nullable final BundleTimelineJson timeline,
@@ -60,8 +62,8 @@ public class BundleJson extends JsonBase {
 
     public BundleJson(final SubscriptionBundle bundle, @Nullable final Currency currency, @Nullable final AccountAuditLogs accountAuditLogs) throws CatalogApiException {
         super(toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForBundle(bundle.getId())));
-        this.accountId = bundle.getAccountId().toString();
-        this.bundleId = bundle.getId().toString();
+        this.accountId = bundle.getAccountId();
+        this.bundleId = bundle.getId();
         this.externalKey = bundle.getExternalKey();
         this.subscriptions = new LinkedList<SubscriptionJson>();
         for (final Subscription subscription : bundle.getSubscriptions()) {
@@ -76,11 +78,11 @@ public class BundleJson extends JsonBase {
         return subscriptions;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
-    public String getBundleId() {
+    public UUID getBundleId() {
         return bundleId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleTimelineJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleTimelineJson.java
index 569cdfa..765096c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleTimelineJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BundleTimelineJson.java
@@ -18,6 +18,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -28,20 +29,20 @@ import org.killbill.billing.util.audit.AccountAuditLogs;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="BundleTimeline")
 public class BundleTimelineJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String bundleId;
+    private final UUID accountId;
+    private final UUID bundleId;
     private final String externalKey;
     private final List<EventSubscriptionJson> events;
 
     @JsonCreator
-    public BundleTimelineJson(@JsonProperty("accountId") @Nullable final String accountId,
-                              @JsonProperty("bundleId") @Nullable final String bundleId,
+    public BundleTimelineJson(@JsonProperty("accountId") @Nullable final UUID accountId,
+                              @JsonProperty("bundleId") @Nullable final UUID bundleId,
                               @JsonProperty("externalKey") @Nullable final String externalKey,
                               @JsonProperty("events") @Nullable final List<EventSubscriptionJson> events,
                               @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
@@ -54,8 +55,8 @@ public class BundleTimelineJson extends JsonBase {
 
     public BundleTimelineJson(final SubscriptionBundleTimeline bundleTimeline, @Nullable final AccountAuditLogs accountAuditLogs) {
         super(toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForBundle(bundleTimeline.getBundleId())));
-        this.accountId = bundleTimeline.getAccountId().toString();
-        this.bundleId = bundleTimeline.getBundleId().toString();
+        this.accountId = bundleTimeline.getAccountId();
+        this.bundleId = bundleTimeline.getBundleId();
         this.externalKey = bundleTimeline.getExternalKey();
 
         this.events = new LinkedList<EventSubscriptionJson>();
@@ -64,11 +65,11 @@ public class BundleTimelineJson extends JsonBase {
         }
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
-    public String getBundleId() {
+    public UUID getBundleId() {
         return bundleId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java
index 55a4375..5a93bc8 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java
@@ -53,7 +53,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Catalog")
 public class CatalogJson {
 
     private final String name;
@@ -212,6 +215,7 @@ public class CatalogJson {
         return result;
     }
 
+    @ApiModel(value="Unit")
     public static class UnitJson {
 
         private final String name;
@@ -261,6 +265,7 @@ public class CatalogJson {
 
     }
 
+    @ApiModel(value="Product")
     public static class ProductJson {
 
         private final String type;
@@ -382,6 +387,7 @@ public class CatalogJson {
         }
     }
 
+    @ApiModel(value="Plan")
     public static class PlanJson {
 
         private final String name;
@@ -473,6 +479,7 @@ public class CatalogJson {
         }
     }
 
+    @ApiModel(value="TieredBlock")
     public static class TieredBlockJson {
         private final String unit;
         private final String size;
@@ -551,6 +558,7 @@ public class CatalogJson {
         }
     }
 
+    @ApiModel(value="Limit")
     public static class LimitJson {
         private final String unit;
         private final String max;
@@ -618,6 +626,7 @@ public class CatalogJson {
         }
     }
 
+    @ApiModel(value="Tier")
     public static class TierJson {
         private final List<TieredBlockJson> blocks;
         private final List<LimitJson> limits;
@@ -696,6 +705,7 @@ public class CatalogJson {
         }
     }
 
+    @ApiModel(value="Usage")
     public static class UsageJson {
         private final String billingPeriod;
         private final List<TierJson> tiers;
@@ -752,6 +762,7 @@ public class CatalogJson {
         }
     }
 
+    @ApiModel(value="Phase")
     public static class PhaseJson {
 
         private final String type;
@@ -917,6 +928,8 @@ public class CatalogJson {
         }
     }
 
+
+    @ApiModel(value="Price")
     public static class PriceJson {
 
         private final String currency;
@@ -979,6 +992,7 @@ public class CatalogJson {
         }
     }
 
+    @ApiModel(value="PriceList")
     public static class PriceListJson {
 
         private String name;
@@ -1044,6 +1058,7 @@ public class CatalogJson {
 
     }
 
+    @ApiModel(value="Duration")
     public static class DurationJson {
 
         private final TimeUnit unit;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboHostedPaymentPageJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboHostedPaymentPageJson.java
index 8e72c5f..0ae0281 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboHostedPaymentPageJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboHostedPaymentPageJson.java
@@ -23,7 +23,9 @@ import javax.annotation.Nullable;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="ComboHostedPaymentPage")
 public class ComboHostedPaymentPageJson extends ComboPaymentJson {
 
     private final HostedPaymentPageFieldsJson hostedPaymentPageFields;
@@ -32,7 +34,7 @@ public class ComboHostedPaymentPageJson extends ComboPaymentJson {
     public ComboHostedPaymentPageJson(@JsonProperty("account") final AccountJson account,
                                       @JsonProperty("paymentMethod") final PaymentMethodJson paymentMethod,
                                       @JsonProperty("hostedPaymentPageFields") final HostedPaymentPageFieldsJson hostedPaymentPageFields,
-                                      @JsonProperty("paymentMethodPluginProperties") final Iterable<PluginPropertyJson> paymentMethodPluginProperties,
+                                      @JsonProperty("paymentMethodPluginProperties") final List<PluginPropertyJson> paymentMethodPluginProperties,
                                       @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(account, paymentMethod, paymentMethodPluginProperties, auditLogs);
         this.hostedPaymentPageFields = hostedPaymentPageFields;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentJson.java
index be99eca..9828010 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentJson.java
@@ -23,17 +23,19 @@ import javax.annotation.Nullable;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="ComboPayment")
 public abstract class ComboPaymentJson extends JsonBase {
 
     private final AccountJson account;
     private final PaymentMethodJson paymentMethod;
-    private final Iterable<PluginPropertyJson> paymentMethodPluginProperties;
+    private final List<PluginPropertyJson> paymentMethodPluginProperties;
 
     @JsonCreator
     public ComboPaymentJson(@JsonProperty("account") final AccountJson account,
                             @JsonProperty("paymentMethod") final PaymentMethodJson paymentMethod,
-                            @JsonProperty("paymentMethodPluginProperties") final Iterable<PluginPropertyJson> paymentMethodPluginProperties,
+                            @JsonProperty("paymentMethodPluginProperties") final List<PluginPropertyJson> paymentMethodPluginProperties,
                             @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
         this.account = account;
@@ -49,7 +51,7 @@ public abstract class ComboPaymentJson extends JsonBase {
         return paymentMethod;
     }
 
-    public Iterable<PluginPropertyJson> getPaymentMethodPluginProperties() {
+    public List<PluginPropertyJson> getPaymentMethodPluginProperties() {
         return paymentMethodPluginProperties;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentTransactionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentTransactionJson.java
index cde1b73..f7b7b4d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentTransactionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentTransactionJson.java
@@ -23,18 +23,20 @@ import javax.annotation.Nullable;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="ComboPaymentTransaction")
 public class ComboPaymentTransactionJson extends ComboPaymentJson {
 
     private final PaymentTransactionJson transaction;
-    private final Iterable<PluginPropertyJson> transactionPluginProperties;
+    private final List<PluginPropertyJson> transactionPluginProperties;
 
     @JsonCreator
     public ComboPaymentTransactionJson(@JsonProperty("account") final AccountJson account,
                                        @JsonProperty("paymentMethod") final PaymentMethodJson paymentMethod,
                                        @JsonProperty("transaction") final PaymentTransactionJson transaction,
-                                       @JsonProperty("paymentMethodPluginProperties") final Iterable<PluginPropertyJson> paymentMethodPluginProperties,
-                                       @JsonProperty("transactionPluginProperties") final Iterable<PluginPropertyJson> transactionPluginProperties,
+                                       @JsonProperty("paymentMethodPluginProperties") final List<PluginPropertyJson> paymentMethodPluginProperties,
+                                       @JsonProperty("transactionPluginProperties") final List<PluginPropertyJson> transactionPluginProperties,
                                        @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(account, paymentMethod, paymentMethodPluginProperties, auditLogs);
         this.transaction = transaction;
@@ -53,7 +55,7 @@ public class ComboPaymentTransactionJson extends ComboPaymentJson {
         return null;
     }
 
-    public Iterable<PluginPropertyJson> getTransactionPluginProperties() {
+    public List<PluginPropertyJson> getTransactionPluginProperties() {
         return transactionPluginProperties;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java
index 886b26d..a65fda4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java
@@ -18,6 +18,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -29,18 +30,19 @@ import org.killbill.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Credit")
 public class CreditJson extends JsonBase {
 
     @ApiModelProperty(required = true)
     private final BigDecimal creditAmount;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String invoiceId;
+    private final UUID invoiceId;
     private final String invoiceNumber;
     private final LocalDate effectiveDate;
-    @ApiModelProperty(dataType = "java.util.UUID", required = true)
-    private final String accountId;
+    @ApiModelProperty(required = true)
+    private final UUID accountId;
     private final String description;
     private final String currency;
 
@@ -48,10 +50,10 @@ public class CreditJson extends JsonBase {
     @JsonCreator
     public CreditJson(@JsonProperty("creditAmount") final BigDecimal creditAmount,
                       @JsonProperty("currency") final String currency,
-                      @JsonProperty("invoiceId") final String invoiceId,
+                      @JsonProperty("invoiceId") final UUID invoiceId,
                       @JsonProperty("invoiceNumber") final String invoiceNumber,
                       @JsonProperty("effectiveDate") final LocalDate effectiveDate,
-                      @JsonProperty("accountId") final String accountId,
+                      @JsonProperty("accountId") final UUID accountId,
                       @JsonProperty("description") final String description,
                       @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
@@ -66,10 +68,10 @@ public class CreditJson extends JsonBase {
 
     public CreditJson(final Invoice invoice, final InvoiceItem credit, final List<AuditLog> auditLogs) {
         super(toAuditLogJson(auditLogs));
-        this.accountId = toString(credit.getAccountId());
+        this.accountId = credit.getAccountId();
         this.creditAmount = credit.getAmount();
         this.currency = credit.getCurrency().name();
-        this.invoiceId = toString(credit.getInvoiceId());
+        this.invoiceId = credit.getInvoiceId();
         this.invoiceNumber = invoice.getInvoiceNumber().toString();
         this.effectiveDate = credit.getStartDate();
         this.description = credit.getDescription();
@@ -83,7 +85,7 @@ public class CreditJson extends JsonBase {
         return creditAmount;
     }
 
-    public String getInvoiceId() {
+    public UUID getInvoiceId() {
         return invoiceId;
     }
 
@@ -95,7 +97,7 @@ public class CreditJson extends JsonBase {
         return effectiveDate;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CustomFieldJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CustomFieldJson.java
index 375b72d..6695075 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CustomFieldJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CustomFieldJson.java
@@ -17,6 +17,7 @@
 package org.killbill.billing.jaxrs.json;
 
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -26,14 +27,14 @@ import org.killbill.billing.util.customfield.CustomField;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="CustomField")
 public class CustomFieldJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String customFieldId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String objectId;
+    private final UUID customFieldId;
+    private final UUID objectId;
     private final ObjectType objectType;
     @ApiModelProperty(required = true)
     private final String name;
@@ -41,8 +42,8 @@ public class CustomFieldJson extends JsonBase {
     private final String value;
 
     @JsonCreator
-    public CustomFieldJson(@JsonProperty("customFieldId") final String customFieldId,
-                           @JsonProperty("objectId") final String objectId,
+    public CustomFieldJson(@JsonProperty("customFieldId") final UUID customFieldId,
+                           @JsonProperty("objectId") final UUID objectId,
                            @JsonProperty("objectType") final ObjectType objectType,
                            @JsonProperty("name") @Nullable final String name,
                            @JsonProperty("value") @Nullable final String value,
@@ -56,14 +57,14 @@ public class CustomFieldJson extends JsonBase {
     }
 
     public CustomFieldJson(final CustomField input, @Nullable final List<AuditLog> auditLogs) {
-        this(input.getId().toString(), input.getObjectId().toString(), input.getObjectType(), input.getFieldName(), input.getFieldValue(), toAuditLogJson(auditLogs));
+        this(input.getId(), input.getObjectId(), input.getObjectType(), input.getFieldName(), input.getFieldValue(), toAuditLogJson(auditLogs));
     }
 
-    public String getCustomFieldId() {
+    public UUID getCustomFieldId() {
         return customFieldId;
     }
 
-    public String getObjectId() {
+    public UUID getObjectId() {
         return objectId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/GatewayNotificationJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/GatewayNotificationJson.java
index b8ef5ca..69d093a 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/GatewayNotificationJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/GatewayNotificationJson.java
@@ -19,6 +19,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
@@ -28,19 +29,20 @@ import org.killbill.billing.payment.plugin.api.GatewayNotification;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="GatewayNotification")
 public class GatewayNotificationJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String kbPaymentId;
+    private final UUID kbPaymentId;
     private final Integer status;
     private final String entity;
     private final Map<String, List<String>> headers;
     private final Map<String, Object> properties;
 
     @JsonCreator
-    public GatewayNotificationJson(@JsonProperty("kbPaymentId") final String kbPaymentId,
+    public GatewayNotificationJson(@JsonProperty("kbPaymentId") final UUID kbPaymentId,
                                    @JsonProperty("status") final Integer status,
                                    @JsonProperty("entity") final String entity,
                                    @JsonProperty("headers") final Map<String, List<String>> headers,
@@ -53,7 +55,7 @@ public class GatewayNotificationJson extends JsonBase {
     }
 
     public GatewayNotificationJson(final GatewayNotification notification) {
-        this.kbPaymentId = notification.getKbPaymentId() == null ? null : notification.getKbPaymentId().toString();
+        this.kbPaymentId = notification.getKbPaymentId();
         this.status = notification.getStatus();
         this.entity = notification.getEntity();
         this.headers = notification.getHeaders();
@@ -78,7 +80,7 @@ public class GatewayNotificationJson extends JsonBase {
         return responseBuilder.build();
     }
 
-    public String getKbPaymentId() {
+    public UUID getKbPaymentId() {
         return kbPaymentId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageBillingAddressJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageBillingAddressJson.java
index a294598..59bcdb4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageBillingAddressJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageBillingAddressJson.java
@@ -18,7 +18,9 @@ package org.killbill.billing.jaxrs.json;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="HostedPaymentPageBillingAddress")
 public class HostedPaymentPageBillingAddressJson extends JsonBase {
 
     private final String city;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageCustomerJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageCustomerJson.java
index 3780c27..6631cac 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageCustomerJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageCustomerJson.java
@@ -18,7 +18,9 @@ package org.killbill.billing.jaxrs.json;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="HostedPaymentPageCustomer")
 public class HostedPaymentPageCustomerJson extends JsonBase {
 
     private final String firstName;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java
index 470f8f8..7f5b638 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java
@@ -20,7 +20,10 @@ import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+
+@ApiModel(value="HostedPaymentPageFields")
 public class HostedPaymentPageFieldsJson extends JsonBase {
 
     private final List<PluginPropertyJson> formFields;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java
index 24b292c..dc7134e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java
@@ -18,24 +18,26 @@
 package org.killbill.billing.jaxrs.json;
 
 import java.util.Map;
+import java.util.UUID;
 
 import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="HostedPaymentPageFormDescriptor")
 public class HostedPaymentPageFormDescriptorJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String kbAccountId;
+    private final UUID kbAccountId;
     private final String formMethod;
     private final String formUrl;
     private final Map<String, Object> formFields;
     private final Map<String, Object> properties;
 
     @JsonCreator
-    public HostedPaymentPageFormDescriptorJson(@JsonProperty("kbAccountId") final String kbAccountId,
+    public HostedPaymentPageFormDescriptorJson(@JsonProperty("kbAccountId") final UUID kbAccountId,
                                                @JsonProperty("formMethod") final String formMethod,
                                                @JsonProperty("formUrl") final String formUrl,
                                                @JsonProperty("formFields") final Map<String, Object> formFields,
@@ -48,14 +50,14 @@ public class HostedPaymentPageFormDescriptorJson extends JsonBase {
     }
 
     public HostedPaymentPageFormDescriptorJson(final HostedPaymentPageFormDescriptor descriptor) {
-        this.kbAccountId = descriptor.getKbAccountId().toString();
+        this.kbAccountId = descriptor.getKbAccountId();
         this.formMethod = descriptor.getFormMethod();
         this.formUrl = descriptor.getFormUrl();
         this.formFields = propertiesToMap(descriptor.getFormFields());
         this.properties = propertiesToMap(descriptor.getProperties());
     }
 
-    public String getKbAccountId() {
+    public UUID getKbAccountId() {
         return kbAccountId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceDryRunJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceDryRunJson.java
index bc82ab3..42493da 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceDryRunJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceDryRunJson.java
@@ -18,6 +18,7 @@
 package org.killbill.billing.jaxrs.json;
 
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -25,7 +26,9 @@ import org.joda.time.LocalDate;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="InvoiceDryRun")
 public class InvoiceDryRunJson {
 
     private final String dryRunType;
@@ -36,8 +39,8 @@ public class InvoiceDryRunJson {
     private final String billingPeriod;
     private final String priceListName;
     private final LocalDate effectiveDate;
-    private final String subscriptionId;
-    private final String bundleId;
+    private final UUID subscriptionId;
+    private final UUID bundleId;
     private final String billingPolicy;
     private final List<PhasePriceOverrideJson> priceOverrides;
 
@@ -49,8 +52,8 @@ public class InvoiceDryRunJson {
                              @JsonProperty("productCategory") @Nullable final String productCategory,
                              @JsonProperty("billingPeriod") @Nullable final String billingPeriod,
                              @JsonProperty("priceListName") @Nullable final String priceListName,
-                             @JsonProperty("subscriptionId") @Nullable final String subscriptionId,
-                             @JsonProperty("bundleId") @Nullable final String bundleId,
+                             @JsonProperty("subscriptionId") @Nullable final UUID subscriptionId,
+                             @JsonProperty("bundleId") @Nullable final UUID bundleId,
                              @JsonProperty("effectiveDate") @Nullable final LocalDate effectiveDate,
                              @JsonProperty("billingPolicy") @Nullable final String billingPolicy,
                              @JsonProperty("priceOverrides") @Nullable final List<PhasePriceOverrideJson> priceOverrides) {
@@ -96,7 +99,7 @@ public class InvoiceDryRunJson {
         return priceListName;
     }
 
-    public String getSubscriptionId() {
+    public UUID getSubscriptionId() {
         return subscriptionId;
     }
 
@@ -104,7 +107,7 @@ public class InvoiceDryRunJson {
         return effectiveDate;
     }
 
-    public String getBundleId() {
+    public UUID getBundleId() {
         return bundleId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceEmailJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceEmailJson.java
index 2eb503c..9dee36c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceEmailJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceEmailJson.java
@@ -16,25 +16,28 @@
 
 package org.killbill.billing.jaxrs.json;
 
+import java.util.UUID;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonGetter;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="InvoiceEmail")
 public class InvoiceEmailJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
+    private final UUID accountId;
     private final boolean isNotifiedForInvoices;
 
     @JsonCreator
-    public InvoiceEmailJson(@JsonProperty("accountId") final String accountId,
+    public InvoiceEmailJson(@JsonProperty("accountId") final UUID accountId,
                             @JsonProperty("isNotifiedForInvoices") final boolean isNotifiedForInvoices) {
         this.accountId = accountId;
         this.isNotifiedForInvoices = isNotifiedForInvoices;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java
index fba3f1e..f19cc88 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java
@@ -34,24 +34,21 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="InvoiceItem")
 public class InvoiceItemJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID", required = true)
-    private final String invoiceItemId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String invoiceId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String linkedInvoiceItemId;
-    @ApiModelProperty(dataType = "java.util.UUID", required = true)
-    private final String accountId;
-    @ApiModelProperty(dataType = "java.util.UUID", required = false)
-    private final String childAccountId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String bundleId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String subscriptionId;
+    @ApiModelProperty( required = true)
+    private final UUID invoiceItemId;
+    private final UUID invoiceId;
+    private final UUID linkedInvoiceItemId;
+    @ApiModelProperty(required = true)
+    private final UUID accountId;
+    private final UUID childAccountId;
+    private final UUID bundleId;
+    private final UUID subscriptionId;
     private final String planName;
     private final String phaseName;
     private final String usageName;
@@ -70,13 +67,13 @@ public class InvoiceItemJson extends JsonBase {
     private List<InvoiceItemJson> childItems;
 
     @JsonCreator
-    public InvoiceItemJson(@JsonProperty("invoiceItemId") final String invoiceItemId,
-                           @JsonProperty("invoiceId") final String invoiceId,
-                           @JsonProperty("linkedInvoiceItemId") final String linkedInvoiceItemId,
-                           @JsonProperty("accountId") final String accountId,
-                           @JsonProperty("childAccountId") final String childAccountId,
-                           @JsonProperty("bundleId") final String bundleId,
-                           @JsonProperty("subscriptionId") final String subscriptionId,
+    public InvoiceItemJson(@JsonProperty("invoiceItemId") final UUID invoiceItemId,
+                           @JsonProperty("invoiceId") final UUID invoiceId,
+                           @JsonProperty("linkedInvoiceItemId") final UUID linkedInvoiceItemId,
+                           @JsonProperty("accountId") final UUID accountId,
+                           @JsonProperty("childAccountId") final UUID childAccountId,
+                           @JsonProperty("bundleId") final UUID bundleId,
+                           @JsonProperty("subscriptionId") final UUID subscriptionId,
                            @JsonProperty("planName") final String planName,
                            @JsonProperty("phaseName") final String phaseName,
                            @JsonProperty("usageName") final String usageName,
@@ -121,8 +118,8 @@ public class InvoiceItemJson extends JsonBase {
     }
 
     public InvoiceItemJson(final InvoiceItem item, final List<InvoiceItem> childItems, @Nullable final List<AuditLog> auditLogs) {
-        this(toString(item.getId()), toString(item.getInvoiceId()), toString(item.getLinkedItemId()),
-             toString(item.getAccountId()), toString(item.getChildAccountId()), toString(item.getBundleId()), toString(item.getSubscriptionId()),
+        this(item.getId(), item.getInvoiceId(), item.getLinkedItemId(),
+             item.getAccountId(), item.getChildAccountId(), item.getBundleId(), item.getSubscriptionId(),
              item.getPlanName(), item.getPhaseName(), item.getUsageName(),
              item.getPrettyPlanName(), item.getPrettyPhaseName(), item.getPrettyUsageName(),
              item.getInvoiceItemType().toString(),
@@ -152,17 +149,17 @@ public class InvoiceItemJson extends JsonBase {
 
             @Override
             public UUID getInvoiceId() {
-                return invoiceId != null ? UUID.fromString(invoiceId) : null;
+                return invoiceId;
             }
 
             @Override
             public UUID getAccountId() {
-                return accountId != null ? UUID.fromString(accountId) : null;
+                return accountId;
             }
 
             @Override
             public UUID getChildAccountId() {
-                return childAccountId != null ? UUID.fromString(childAccountId) : null;
+                return childAccountId;
             }
 
             @Override
@@ -192,12 +189,12 @@ public class InvoiceItemJson extends JsonBase {
 
             @Override
             public UUID getBundleId() {
-                return bundleId != null ? UUID.fromString(bundleId) : null;
+                return bundleId;
             }
 
             @Override
             public UUID getSubscriptionId() {
-                return subscriptionId != null ? UUID.fromString(subscriptionId) : null;
+                return subscriptionId;
             }
 
             @Override
@@ -237,7 +234,7 @@ public class InvoiceItemJson extends JsonBase {
 
             @Override
             public UUID getLinkedItemId() {
-                return linkedInvoiceItemId != null ? UUID.fromString(linkedInvoiceItemId) : null;
+                return linkedInvoiceItemId;
             }
 
             @Override
@@ -272,31 +269,31 @@ public class InvoiceItemJson extends JsonBase {
         this(input, null, null);
     }
 
-    public String getInvoiceItemId() {
+    public UUID getInvoiceItemId() {
         return invoiceItemId;
     }
 
-    public String getInvoiceId() {
+    public UUID getInvoiceId() {
         return invoiceId;
     }
 
-    public String getLinkedInvoiceItemId() {
+    public UUID getLinkedInvoiceItemId() {
         return linkedInvoiceItemId;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
-    public String getChildAccountId() {
+    public UUID getChildAccountId() {
         return childAccountId;
     }
 
-    public String getBundleId() {
+    public UUID getBundleId() {
         return bundleId;
     }
 
-    public String getSubscriptionId() {
+    public UUID getSubscriptionId() {
         return subscriptionId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceJson.java
index 36af2b2..10568e2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceJson.java
@@ -19,6 +19,7 @@ package org.killbill.billing.jaxrs.json;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -35,29 +36,29 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Invoice")
 public class InvoiceJson extends JsonBase {
 
     private final BigDecimal amount;
     private final String currency;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String invoiceId;
+    private final UUID invoiceId;
     private final LocalDate invoiceDate;
     private final LocalDate targetDate;
     private final String invoiceNumber;
     private final BigDecimal balance;
     private final BigDecimal creditAdj;
     private final BigDecimal refundAdj;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
+    private final UUID accountId;
     private final List<InvoiceItemJson> items;
     private final String bundleKeys;
     private final List<CreditJson> credits;
     private final String status;
     private final Boolean isParentInvoice;
-    private final String parentInvoiceId;
-    private final String parentAccountId;
+    private final UUID parentInvoiceId;
+    private final UUID parentAccountId;
 
     @JsonCreator
     public InvoiceJson(@JsonProperty("amount") final BigDecimal amount,
@@ -65,18 +66,18 @@ public class InvoiceJson extends JsonBase {
                        @JsonProperty("status") final String status,
                        @JsonProperty("creditAdj") final BigDecimal creditAdj,
                        @JsonProperty("refundAdj") final BigDecimal refundAdj,
-                       @JsonProperty("invoiceId") final String invoiceId,
+                       @JsonProperty("invoiceId") final UUID invoiceId,
                        @JsonProperty("invoiceDate") final LocalDate invoiceDate,
                        @JsonProperty("targetDate") final LocalDate targetDate,
                        @JsonProperty("invoiceNumber") final String invoiceNumber,
                        @JsonProperty("balance") final BigDecimal balance,
-                       @JsonProperty("accountId") final String accountId,
+                       @JsonProperty("accountId") final UUID accountId,
                        @JsonProperty("bundleKeys") final String bundleKeys,
                        @JsonProperty("credits") final List<CreditJson> credits,
                        @JsonProperty("items") final List<InvoiceItemJson> items,
                        @JsonProperty("isParentInvoice") final Boolean isParentInvoice,
-                       @JsonProperty("parentInvoiceId") final String parentInvoiceId,
-                       @JsonProperty("parentAccountId") final String parentAccountId,
+                       @JsonProperty("parentInvoiceId") final UUID parentInvoiceId,
+                       @JsonProperty("parentAccountId") final UUID parentAccountId,
                        @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
         this.amount = amount;
@@ -104,10 +105,10 @@ public class InvoiceJson extends JsonBase {
 
     public InvoiceJson(final Invoice input, final String bundleKeys, final List<CreditJson> credits, final List<AuditLog> auditLogs) {
         this(input.getChargedAmount(), input.getCurrency().toString(), input.getStatus().toString(), input.getCreditedAmount(), input.getRefundedAmount(),
-             input.getId().toString(), input.getInvoiceDate(), input.getTargetDate(), String.valueOf(input.getInvoiceNumber()),
-             input.getBalance(), input.getAccountId().toString(), bundleKeys, credits, null, input.isParentInvoice(),
-             input.getParentInvoiceId() != null ? input.getParentInvoiceId().toString() : null,
-             input.getParentAccountId() != null ? input.getParentAccountId().toString() : null,
+             input.getId(), input.getInvoiceDate(), input.getTargetDate(), String.valueOf(input.getInvoiceNumber()),
+             input.getBalance(), input.getAccountId(), bundleKeys, credits, null, input.isParentInvoice(),
+             input.getParentInvoiceId(),
+             input.getParentAccountId(),
              toAuditLogJson(auditLogs));
     }
 
@@ -133,17 +134,17 @@ public class InvoiceJson extends JsonBase {
         this.status = input.getStatus().toString();
         this.creditAdj = input.getCreditedAmount();
         this.refundAdj = input.getRefundedAmount();
-        this.invoiceId = input.getId().toString();
+        this.invoiceId = input.getId();
         this.invoiceDate = input.getInvoiceDate();
         this.targetDate = input.getTargetDate();
         this.invoiceNumber = input.getInvoiceNumber() == null ? null : String.valueOf(input.getInvoiceNumber());
         this.balance = input.getBalance();
-        this.accountId = input.getAccountId().toString();
+        this.accountId = input.getAccountId();
         this.bundleKeys = null;
         this.credits = null;
         this.isParentInvoice = input.isParentInvoice();
-        this.parentInvoiceId = input.getParentInvoiceId() != null ? input.getParentInvoiceId().toString() : null;
-        this.parentAccountId = input.getParentAccountId() != null ? input.getParentAccountId().toString() : null;
+        this.parentInvoiceId = input.getParentInvoiceId();
+        this.parentAccountId = input.getParentAccountId();
 
     }
 
@@ -155,7 +156,7 @@ public class InvoiceJson extends JsonBase {
         return currency;
     }
 
-    public String getInvoiceId() {
+    public UUID getInvoiceId() {
         return invoiceId;
     }
 
@@ -183,7 +184,7 @@ public class InvoiceJson extends JsonBase {
         return refundAdj;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
@@ -207,11 +208,11 @@ public class InvoiceJson extends JsonBase {
         return isParentInvoice;
     }
 
-    public String getParentInvoiceId() {
+    public UUID getParentInvoiceId() {
         return parentInvoiceId;
     }
 
-    public String getParentAccountId() {
+    public UUID getParentAccountId() {
         return parentAccountId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
index 7379469..8697e9a 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
@@ -30,18 +30,19 @@ import org.killbill.billing.util.audit.AccountAuditLogs;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="InvoicePayment")
 public class InvoicePaymentJson extends PaymentJson {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String targetInvoiceId;
+    private final UUID targetInvoiceId;
 
 
     @JsonCreator
-    public InvoicePaymentJson(@JsonProperty("targetInvoiceId") final String targetInvoiceId,
-                              @JsonProperty("accountId") final String accountId,
-                              @JsonProperty("paymentId") final String paymentId,
+    public InvoicePaymentJson(@JsonProperty("targetInvoiceId") final UUID targetInvoiceId,
+                              @JsonProperty("accountId") final UUID accountId,
+                              @JsonProperty("paymentId") final UUID paymentId,
                               @JsonProperty("paymentNumber") final String paymentNumber,
                               @JsonProperty("paymentExternalKey") final String paymentExternalKey,
                               @JsonProperty("authAmount") final BigDecimal authAmount,
@@ -50,7 +51,7 @@ public class InvoicePaymentJson extends PaymentJson {
                               @JsonProperty("refundedAmount") final BigDecimal refundedAmount,
                               @JsonProperty("creditedAmount") final BigDecimal creditedAmount,
                               @JsonProperty("currency") final String currency,
-                              @JsonProperty("paymentMethodId") final String paymentMethodId,
+                              @JsonProperty("paymentMethodId") final UUID paymentMethodId,
                               @JsonProperty("transactions") final List<? extends PaymentTransactionJson> transactions,
                               @JsonProperty("paymentAttempts") final List<PaymentAttemptJson> paymentAttempts,
                               @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
@@ -61,11 +62,11 @@ public class InvoicePaymentJson extends PaymentJson {
     public InvoicePaymentJson(final Payment payment, @Nullable final UUID invoiceId, @Nullable final AccountAuditLogs accountAuditLogs) {
         super(payment, accountAuditLogs);
         //  TODO should build InvoicePaymentTransactionJson instead of PaymentTransactionJson here.
-        this.targetInvoiceId = invoiceId != null ? invoiceId.toString() : null;
+        this.targetInvoiceId = invoiceId;
     }
 
 
-        public String getTargetInvoiceId() {
+        public UUID getTargetInvoiceId() {
         return targetInvoiceId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentTransactionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentTransactionJson.java
index 8c03d0e..2635d7a 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentTransactionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentTransactionJson.java
@@ -19,6 +19,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -26,16 +27,18 @@ import org.joda.time.DateTime;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="InvoicePaymentTransaction")
 public class InvoicePaymentTransactionJson extends PaymentTransactionJson {
 
     private final Boolean isAdjusted;
     private final List<InvoiceItemJson> adjustments;
 
     @JsonCreator
-    public InvoicePaymentTransactionJson(@JsonProperty("transactionId") final String transactionId,
+    public InvoicePaymentTransactionJson(@JsonProperty("transactionId") final UUID transactionId,
                                          @JsonProperty("transactionExternalKey") final String transactionExternalKey,
-                                         @JsonProperty("paymentId") final String paymentId,
+                                         @JsonProperty("paymentId") final UUID paymentId,
                                          @JsonProperty("paymentExternalKey") final String paymentExternalKey,
                                          @JsonProperty("transactionType") final String transactionType,
                                          @JsonProperty("amount") final BigDecimal amount,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandJson.java
index ca8ec1f..ffcf1d3 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandJson.java
@@ -23,7 +23,9 @@ import org.killbill.billing.util.nodes.NodeCommandProperty;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="NodeCommand")
 public class NodeCommandJson {
 
     private final boolean systemCommandType;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandPropertyJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandPropertyJson.java
index ef0665b..38cbfe6 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandPropertyJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeCommandPropertyJson.java
@@ -21,7 +21,9 @@ import org.killbill.billing.util.nodes.NodeCommandProperty;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="NodeCommandProperty")
 public class NodeCommandPropertyJson extends NodeCommandProperty {
 
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeInfoJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeInfoJson.java
index 62477c9..389640d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeInfoJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NodeInfoJson.java
@@ -23,7 +23,9 @@ import org.joda.time.DateTime;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="NodeInfo")
 public class NodeInfoJson {
 
     private final String nodeName;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NotificationJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NotificationJson.java
index 2f5fbbe..40e7c5c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NotificationJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/NotificationJson.java
@@ -16,30 +16,33 @@
 
 package org.killbill.billing.jaxrs.json;
 
+import java.util.UUID;
+
 import org.killbill.billing.notification.plugin.api.ExtBusEvent;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 /*
  * Use to communicate back with client after they registered a callback
  */
+
+@ApiModel(value="Notification")
 public class NotificationJson {
 
     private final String eventType;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
+    private final UUID accountId;
     private final String objectType;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String objectId;
+    private final UUID objectId;
     private String metaData;
 
     @JsonCreator
     public NotificationJson(@JsonProperty("eventType") final String eventType,
-                            @JsonProperty("accountId") final String accountId,
+                            @JsonProperty("accountId") final UUID accountId,
                             @JsonProperty("objectType") final String objectType,
-                            @JsonProperty("objectId") final String objectId,
+                            @JsonProperty("objectId") final UUID objectId,
                             @JsonProperty("metaData") final String metaData) {
         this.eventType = eventType;
         this.accountId = accountId;
@@ -50,9 +53,9 @@ public class NotificationJson {
 
     public NotificationJson(final ExtBusEvent event) {
         this(event.getEventType().toString(),
-             event.getAccountId() != null ? event.getAccountId().toString() : null,
+             event.getAccountId(),
              event.getObjectType().toString(),
-             event.getObjectId() != null ? event.getObjectId().toString() : null,
+             event.getObjectId(),
              event.getMetaData());
     }
 
@@ -60,7 +63,7 @@ public class NotificationJson {
         return eventType;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
@@ -68,7 +71,7 @@ public class NotificationJson {
         return objectType;
     }
 
-    public String getObjectId() {
+    public UUID getObjectId() {
         return objectId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueConditionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueConditionJson.java
index a190bd2..3b0b302 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueConditionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueConditionJson.java
@@ -28,7 +28,9 @@ import org.killbill.billing.util.tag.ControlTagType;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="OverdueCondition")
 public class OverdueConditionJson {
 
     private final DurationJson timeSinceEarliestUnpaidInvoiceEqualsOrExceeds;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java
index c2284be..1e30ce4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueJson.java
@@ -35,7 +35,9 @@ import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="Overdue")
 public class OverdueJson {
 
     private final Integer initialReevaluationIntervalDays;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateConfigJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateConfigJson.java
index 0e8a4c4..9a509ab 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateConfigJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateConfigJson.java
@@ -23,7 +23,9 @@ import org.killbill.billing.overdue.api.OverdueState;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="OverdueStateConfig")
 public class OverdueStateConfigJson {
 
     private final String name;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateJson.java
index 4ab3eab..ef5f7fa 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/OverdueStateJson.java
@@ -25,7 +25,9 @@ import org.killbill.billing.util.config.definition.PaymentConfig;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="OverdueState")
 public class OverdueStateJson {
 
     private final String name;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java
index 17763cf..6206614 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java
@@ -19,6 +19,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -31,16 +32,13 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
-@ApiModel(description = "Payment attempt")
+@ApiModel(value="PaymentAttempt")
 public class PaymentAttemptJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String paymentMethodId;
+    private final UUID accountId;
+    private final UUID paymentMethodId;
     private final String paymentExternalKey;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String transactionId;
+    private final UUID transactionId;
     private final String transactionExternalKey;
     @ApiModelProperty(dataType = "org.killbill.billing.payment.api.TransactionType")
     private final String transactionType;
@@ -56,10 +54,10 @@ public class PaymentAttemptJson extends JsonBase {
     private final List<PluginPropertyJson> pluginProperties;
 
     @JsonCreator
-    public PaymentAttemptJson(@JsonProperty("accountId") final String accountId,
-                              @JsonProperty("paymentMethodId") final String paymentMethodId,
+    public PaymentAttemptJson(@JsonProperty("accountId") final UUID accountId,
+                              @JsonProperty("paymentMethodId") final UUID paymentMethodId,
                               @JsonProperty("paymentExternalKey") final String paymentExternalKey,
-                              @JsonProperty("transactionId") final String transactionId,
+                              @JsonProperty("transactionId") final UUID transactionId,
                               @JsonProperty("transactionExternalKey") final String transactionExternalKey,
                               @JsonProperty("transactionType") final String transactionType,
                               @JsonProperty("effectiveDate") final DateTime effectiveDate,
@@ -85,11 +83,11 @@ public class PaymentAttemptJson extends JsonBase {
     }
 
     public PaymentAttemptJson(final PaymentAttempt paymentAttempt, final String paymentExternalKey, @Nullable final List<AuditLog> attemptsLogs) {
-        this(paymentAttempt.getAccountId().toString(),
+        this(paymentAttempt.getAccountId(),
              // Could be null if aborted in the priorCall
-             paymentAttempt.getPaymentMethodId() != null ? paymentAttempt.getPaymentMethodId().toString() : null,
+             paymentAttempt.getPaymentMethodId(),
              paymentExternalKey,
-             paymentAttempt.getTransactionId() != null ? paymentAttempt.getTransactionId().toString() : null,
+             paymentAttempt.getTransactionId(),
              paymentAttempt.getTransactionExternalKey(),
              paymentAttempt.getTransactionType().toString(),
              paymentAttempt.getEffectiveDate(),
@@ -101,11 +99,11 @@ public class PaymentAttemptJson extends JsonBase {
              toAuditLogJson(attemptsLogs));
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
-    public String getPaymentMethodId() {
+    public UUID getPaymentMethodId() {
         return paymentMethodId;
     }
 
@@ -113,7 +111,7 @@ public class PaymentAttemptJson extends JsonBase {
         return paymentExternalKey;
     }
 
-    public String getTransactionId() {
+    public UUID getTransactionId() {
         return transactionId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
index 4a605fa..674d00e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
@@ -18,6 +18,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -32,14 +33,14 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Payment")
 public class PaymentJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String paymentId;
+    private final UUID accountId;
+    private final UUID paymentId;
     private final String paymentNumber;
     private final String paymentExternalKey;
     private final BigDecimal authAmount;
@@ -48,14 +49,13 @@ public class PaymentJson extends JsonBase {
     private final BigDecimal refundedAmount;
     private final BigDecimal creditedAmount;
     private final String currency;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String paymentMethodId;
+    private final UUID paymentMethodId;
     private final List<? extends PaymentTransactionJson> transactions;
     private final List<PaymentAttemptJson> paymentAttempts;
 
     @JsonCreator
-    public PaymentJson(@JsonProperty("accountId") final String accountId,
-                       @JsonProperty("paymentId") final String paymentId,
+    public PaymentJson(@JsonProperty("accountId") final UUID accountId,
+                       @JsonProperty("paymentId") final UUID paymentId,
                        @JsonProperty("paymentNumber") final String paymentNumber,
                        @JsonProperty("paymentExternalKey") final String paymentExternalKey,
                        @JsonProperty("authAmount") final BigDecimal authAmount,
@@ -64,7 +64,7 @@ public class PaymentJson extends JsonBase {
                        @JsonProperty("refundedAmount") final BigDecimal refundedAmount,
                        @JsonProperty("creditedAmount") final BigDecimal creditedAmount,
                        @JsonProperty("currency") final String currency,
-                       @JsonProperty("paymentMethodId") final String paymentMethodId,
+                       @JsonProperty("paymentMethodId") final UUID paymentMethodId,
                        @JsonProperty("transactions") final List<? extends PaymentTransactionJson> transactions,
                        @JsonProperty("paymentAttempts") final List<PaymentAttemptJson> paymentAttempts,
                        @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
@@ -85,8 +85,8 @@ public class PaymentJson extends JsonBase {
     }
 
     public PaymentJson(final Payment dp, @Nullable final AccountAuditLogs accountAuditLogs) {
-        this(dp.getAccountId().toString(),
-             dp.getId().toString(),
+        this(dp.getAccountId(),
+             dp.getId(),
              dp.getPaymentNumber().toString(),
              dp.getExternalKey(),
              dp.getAuthAmount(),
@@ -95,7 +95,7 @@ public class PaymentJson extends JsonBase {
              dp.getRefundedAmount(),
              dp.getCreditedAmount(),
              dp.getCurrency() != null ? dp.getCurrency().toString() : null,
-             dp.getPaymentMethodId() != null ? dp.getPaymentMethodId().toString() : null,
+             dp.getPaymentMethodId(),
              getTransactions(dp.getTransactions(), dp.getExternalKey(), accountAuditLogs),
              getAttempts(dp.getPaymentAttempts(), dp.getExternalKey(), accountAuditLogs),
              toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForPayment(dp.getId())));
@@ -125,11 +125,11 @@ public class PaymentJson extends JsonBase {
                                                        )) : null;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
-    public String getPaymentId() {
+    public UUID getPaymentId() {
         return paymentId;
     }
 
@@ -165,7 +165,7 @@ public class PaymentJson extends JsonBase {
         return currency;
     }
 
-    public String getPaymentMethodId() {
+    public UUID getPaymentMethodId() {
         return paymentMethodId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
index 6a6d997..0f72911 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
@@ -37,23 +37,23 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="PaymentMethod")
 public class PaymentMethodJson extends JsonBase {
 
     private final String externalKey;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String paymentMethodId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
+    private final UUID paymentMethodId;
+    private final UUID accountId;
     private final Boolean isDefault;
     private final String pluginName;
     private final PaymentMethodPluginDetailJson pluginInfo;
 
     @JsonCreator
-    public PaymentMethodJson(@JsonProperty("paymentMethodId") final String paymentMethodId,
+    public PaymentMethodJson(@JsonProperty("paymentMethodId") final UUID paymentMethodId,
                              @JsonProperty("externalKey") final String externalKey,
-                             @JsonProperty("accountId") final String accountId,
+                             @JsonProperty("accountId") final UUID accountId,
                              @JsonProperty("isDefault") final Boolean isDefault,
                              @JsonProperty("pluginName") final String pluginName,
                              @JsonProperty("pluginInfo") @Nullable final PaymentMethodPluginDetailJson pluginInfo,
@@ -86,11 +86,11 @@ public class PaymentMethodJson extends JsonBase {
                                                                  pluginDetail.isDefaultPaymentMethod(),
                                                                  properties);
         }
-        return new PaymentMethodJson(in.getId().toString(), in.getExternalKey(), account.getId().toString(), isDefault, in.getPluginName(),
+        return new PaymentMethodJson(in.getId(), in.getExternalKey(), account.getId(), isDefault, in.getPluginName(),
                                      pluginDetailJson, toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForPaymentMethod(in.getId())));
     }
 
-    public PaymentMethod toPaymentMethod(final String accountId) {
+    public PaymentMethod toPaymentMethod(final UUID accountId) {
         return new PaymentMethod() {
             @Override
             public Boolean isActive() {
@@ -104,7 +104,7 @@ public class PaymentMethodJson extends JsonBase {
 
             @Override
             public UUID getId() {
-                return paymentMethodId != null ? UUID.fromString(paymentMethodId) : null;
+                return paymentMethodId;
             }
 
             @Override
@@ -124,7 +124,7 @@ public class PaymentMethodJson extends JsonBase {
 
             @Override
             public UUID getAccountId() {
-                return UUID.fromString(accountId);
+                return accountId;
             }
 
             @Override
@@ -132,7 +132,7 @@ public class PaymentMethodJson extends JsonBase {
                 return new PaymentMethodPlugin() {
                     @Override
                     public UUID getKbPaymentMethodId() {
-                        return paymentMethodId == null ? null : UUID.fromString(paymentMethodId);
+                        return paymentMethodId;
                     }
 
                     @Override
@@ -162,11 +162,11 @@ public class PaymentMethodJson extends JsonBase {
         };
     }
 
-    public String getPaymentMethodId() {
+    public UUID getPaymentMethodId() {
         return paymentMethodId;
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
@@ -240,6 +240,8 @@ public class PaymentMethodJson extends JsonBase {
         return result;
     }
 
+
+    @ApiModel(value="PaymentMethodPluginDetail")
     public static class PaymentMethodPluginDetailJson {
 
         private final String externalPaymentMethodId;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentTransactionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentTransactionJson.java
index be81a3a..7b6c89c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentTransactionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentTransactionJson.java
@@ -18,6 +18,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -30,14 +31,13 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
-@ApiModel(description = "Payment transaction")
+@ApiModel(value="PaymentTransaction")
 public class PaymentTransactionJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String transactionId;
+    private final UUID transactionId;
     private final String transactionExternalKey;
-    @ApiModelProperty(value = "Associated payment id, required when notifying state transitions", dataType = "java.util.UUID")
-    private final String paymentId;
+    @ApiModelProperty(value = "Associated payment id, required when notifying state transitions")
+    private final UUID paymentId;
     private final String paymentExternalKey;
     @ApiModelProperty(dataType = "org.killbill.billing.payment.api.TransactionType")
     private final String transactionType;
@@ -59,9 +59,9 @@ public class PaymentTransactionJson extends JsonBase {
     private final List<PluginPropertyJson> properties;
 
     @JsonCreator
-    public PaymentTransactionJson(@JsonProperty("transactionId") final String transactionId,
+    public PaymentTransactionJson(@JsonProperty("transactionId") final UUID transactionId,
                                   @JsonProperty("transactionExternalKey") final String transactionExternalKey,
-                                  @JsonProperty("paymentId") final String paymentId,
+                                  @JsonProperty("paymentId") final UUID paymentId,
                                   @JsonProperty("paymentExternalKey") final String paymentExternalKey,
                                   @JsonProperty("transactionType") final String transactionType,
                                   @JsonProperty("amount") final BigDecimal amount,
@@ -96,9 +96,9 @@ public class PaymentTransactionJson extends JsonBase {
     }
 
     public PaymentTransactionJson(final PaymentTransaction transaction, final String paymentExternalKey, @Nullable final List<AuditLog> transactionLogs) {
-        this(transaction.getId().toString(),
+        this(transaction.getId(),
              transaction.getExternalKey(),
-             transaction.getPaymentId().toString(),
+             transaction.getPaymentId(),
              paymentExternalKey,
              transaction.getTransactionType().toString(),
              transaction.getAmount(),
@@ -115,11 +115,11 @@ public class PaymentTransactionJson extends JsonBase {
              toAuditLogJson(transactionLogs));
     }
 
-    public String getTransactionId() {
+    public UUID getTransactionId() {
         return transactionId;
     }
 
-    public String getPaymentId() {
+    public UUID getPaymentId() {
         return paymentId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java
index 77d27f4..087d44f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PhasePriceOverrideJson.java
@@ -46,7 +46,9 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="PhasePriceOverride")
 public class PhasePriceOverrideJson {
 
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PlanDetailJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PlanDetailJson.java
index 371d9f3..50f7350 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PlanDetailJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PlanDetailJson.java
@@ -31,7 +31,9 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="PlanDetail")
 public class PlanDetailJson {
 
     final String product;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginInfoJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginInfoJson.java
index 13e4bbc..6d10169 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginInfoJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginInfoJson.java
@@ -27,7 +27,9 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="PluginInfo")
 public class PluginInfoJson {
 
     private final String bundleSymbolicName;
@@ -105,6 +107,7 @@ public class PluginInfoJson {
         return services;
     }
 
+    @ApiModel(value="PluginServiceInfo")
     public static class PluginServiceInfoJson {
 
         private final String serviceTypeName;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginPropertyJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginPropertyJson.java
index 40c02c5..1eed1fb 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginPropertyJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginPropertyJson.java
@@ -21,7 +21,9 @@ import org.killbill.billing.payment.api.PluginProperty;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="PluginProperty")
 public class PluginPropertyJson {
 
     private final String key;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java
index f3a9ce4..2158431 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java
@@ -30,7 +30,9 @@ import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Preconditions;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="ProfilingData")
 public class ProfilingDataJson {
 
     private final List<ProfilingDataJsonItem> rawData;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RoleDefinitionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RoleDefinitionJson.java
index 1417203..27730e5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RoleDefinitionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RoleDefinitionJson.java
@@ -21,8 +21,10 @@ import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="RoleDefinition")
 public class RoleDefinitionJson {
 
     @ApiModelProperty(required = true)
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RolledUpUsageJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RolledUpUsageJson.java
index f07ac02..64dce49 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RolledUpUsageJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/RolledUpUsageJson.java
@@ -17,6 +17,7 @@
 package org.killbill.billing.jaxrs.json;
 
 import java.util.List;
+import java.util.UUID;
 
 import org.joda.time.LocalDate;
 import org.killbill.billing.usage.api.RolledUpUnit;
@@ -27,18 +28,19 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="RolledUpUsage")
 public class RolledUpUsageJson {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String subscriptionId;
+    private final UUID subscriptionId;
     private final LocalDate startDate;
     private final LocalDate endDate;
     private final List<RolledUpUnitJson> rolledUpUnits;
 
     @JsonCreator
-    public RolledUpUsageJson(@JsonProperty("subscriptionId") final String subscriptionId,
+    public RolledUpUsageJson(@JsonProperty("subscriptionId") final UUID subscriptionId,
                              @JsonProperty("startDate") final LocalDate startDate,
                              @JsonProperty("endDate") final LocalDate endDate,
                              @JsonProperty("rolledUpUnits") final List<RolledUpUnitJson> rolledUpUnits) {
@@ -49,7 +51,7 @@ public class RolledUpUsageJson {
     }
 
     public RolledUpUsageJson(final RolledUpUsage input) {
-        this(input.getSubscriptionId().toString(), input.getStart(), input.getEnd(), ImmutableList.copyOf(Iterables.transform(input.getRolledUpUnits(), new Function<RolledUpUnit, RolledUpUnitJson>() {
+        this(input.getSubscriptionId(), input.getStart(), input.getEnd(), ImmutableList.copyOf(Iterables.transform(input.getRolledUpUnits(), new Function<RolledUpUnit, RolledUpUnitJson>() {
             @Override
             public RolledUpUnitJson apply(final RolledUpUnit input) {
                 return new RolledUpUnitJson(input);
@@ -57,7 +59,7 @@ public class RolledUpUsageJson {
         })));
     }
 
-    public String getSubscriptionId() {
+    public UUID getSubscriptionId() {
         return subscriptionId;
     }
 
@@ -73,6 +75,7 @@ public class RolledUpUsageJson {
         return rolledUpUnits;
     }
 
+    @ApiModel(value="RolledUpUnit")
     public static class RolledUpUnitJson {
 
         private final String unitType;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SessionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SessionJson.java
index 1e28fbf..7f0c241 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SessionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SessionJson.java
@@ -22,8 +22,10 @@ import org.joda.time.DateTimeZone;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Session")
 public class SessionJson {
 
     private final String id;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SimplePlanJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SimplePlanJson.java
index 1c9bb24..2b985b6 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SimplePlanJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SimplePlanJson.java
@@ -27,7 +27,9 @@ import org.killbill.billing.catalog.api.TimeUnit;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="SimplePlan")
 public class SimplePlanJson {
 
     private final String planId;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubjectJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubjectJson.java
index 7f95d87..a415acd 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubjectJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubjectJson.java
@@ -23,7 +23,9 @@ import org.apache.shiro.subject.Subject;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="Subject")
 public class SubjectJson {
 
     private final String principal;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
index 8afb59e..cd3eae0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -41,16 +42,15 @@ import org.killbill.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Subscription")
 public class SubscriptionJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String accountId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String bundleId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String subscriptionId;
+    private final UUID accountId;
+    private final UUID bundleId;
+    private final UUID subscriptionId;
     private final String externalKey;
     private final LocalDate startDate;
     @ApiModelProperty(required = true)
@@ -79,9 +79,10 @@ public class SubscriptionJson extends JsonBase {
     private final List<EventSubscriptionJson> events;
     private final List<PhasePriceOverrideJson> priceOverrides;
 
+    @ApiModel(value="EventSubscription")
     public static class EventSubscriptionJson extends JsonBase {
 
-        private final String eventId;
+        private final UUID eventId;
         private final String billingPeriod;
         private final LocalDate effectiveDate;
         private final String plan;
@@ -96,7 +97,7 @@ public class SubscriptionJson extends JsonBase {
         private final String serviceStateName;
 
         @JsonCreator
-        public EventSubscriptionJson(@JsonProperty("eventId") final String eventId,
+        public EventSubscriptionJson(@JsonProperty("eventId") final UUID eventId,
                                      @JsonProperty("billingPeriod") final String billingPeriod,
                                      @JsonProperty("effectiveDate") final LocalDate effectiveDate,
                                      @JsonProperty("plan") final String plan,
@@ -132,7 +133,7 @@ public class SubscriptionJson extends JsonBase {
             final Product product = subscriptionEvent.getNextProduct() != null ? subscriptionEvent.getNextProduct() : subscriptionEvent.getPrevProduct();
             final PriceList priceList = subscriptionEvent.getNextPriceList() != null ? subscriptionEvent.getNextPriceList() : subscriptionEvent.getPrevPriceList();
             final PlanPhase phase = subscriptionEvent.getNextPhase() != null ? subscriptionEvent.getNextPhase() : subscriptionEvent.getPrevPhase();
-            this.eventId = subscriptionEvent.getId().toString();
+            this.eventId = subscriptionEvent.getId();
             this.billingPeriod = billingPeriod != null ? billingPeriod.toString() : null;
             this.effectiveDate = subscriptionEvent.getEffectiveDate();
             this.plan = plan != null ? plan.getName() : null;
@@ -160,7 +161,7 @@ public class SubscriptionJson extends JsonBase {
             throw new IllegalStateException("Unepxected objectType " + subscriptionEventObjectType + " for SubscriptionEvent " + subscriptionEvent.getId());
         }
 
-        public String getEventId() {
+        public UUID getEventId() {
             return eventId;
         }
 
@@ -297,9 +298,9 @@ public class SubscriptionJson extends JsonBase {
     }
 
     @JsonCreator
-    public SubscriptionJson(@JsonProperty("accountId") @Nullable final String accountId,
-                            @JsonProperty("bundleId") @Nullable final String bundleId,
-                            @JsonProperty("subscriptionId") @Nullable final String subscriptionId,
+    public SubscriptionJson(@JsonProperty("accountId") @Nullable final UUID accountId,
+                            @JsonProperty("bundleId") @Nullable final UUID bundleId,
+                            @JsonProperty("subscriptionId") @Nullable final UUID subscriptionId,
                             @JsonProperty("externalKey") @Nullable final String externalKey,
                             @JsonProperty("startDate") @Nullable final LocalDate startDate,
                             @JsonProperty("productName") @Nullable final String productName,
@@ -387,9 +388,9 @@ public class SubscriptionJson extends JsonBase {
         this.billingStartDate = subscription.getBillingStartDate();
         this.billingEndDate = subscription.getBillingEndDate();
         this.billCycleDayLocal = subscription.getBillCycleDayLocal();
-        this.accountId = subscription.getAccountId().toString();
-        this.bundleId = subscription.getBundleId().toString();
-        this.subscriptionId = subscription.getId().toString();
+        this.accountId = subscription.getAccountId();
+        this.bundleId = subscription.getBundleId();
+        this.subscriptionId = subscription.getId();
         this.externalKey = subscription.getExternalKey();
         this.events = new LinkedList<EventSubscriptionJson>();
         // We fill the catalog info every time we get the currency from the account (even if this is not overridden Plan)
@@ -420,15 +421,15 @@ public class SubscriptionJson extends JsonBase {
         }
     }
 
-    public String getAccountId() {
+    public UUID getAccountId() {
         return accountId;
     }
 
-    public String getBundleId() {
+    public UUID getBundleId() {
         return bundleId;
     }
 
-    public String getSubscriptionId() {
+    public UUID getSubscriptionId() {
         return subscriptionId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionUsageRecordJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionUsageRecordJson.java
index 23cc0e8..c961eb4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionUsageRecordJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionUsageRecordJson.java
@@ -31,19 +31,21 @@ import com.google.common.base.Function;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="SubscriptionUsageRecord")
 public class SubscriptionUsageRecordJson {
 
-    @ApiModelProperty(dataType = "java.util.UUID", required = true)
-    private final String subscriptionId;
+    @ApiModelProperty(required = true)
+    private final UUID subscriptionId;
     @ApiModelProperty(required = true)
     private final List<UnitUsageRecordJson> unitUsageRecords;
     @ApiModelProperty(required = false)
     private final String trackingId;
 
     @JsonCreator
-    public SubscriptionUsageRecordJson(@JsonProperty("subscriptionId") final String subscriptionId,
+    public SubscriptionUsageRecordJson(@JsonProperty("subscriptionId") final UUID subscriptionId,
                                        @JsonProperty("trackingId") final String trackingId,
                                        @JsonProperty("unitUsageRecords") final List<UnitUsageRecordJson> unitUsageRecords) {
         this.subscriptionId = subscriptionId;
@@ -51,7 +53,7 @@ public class SubscriptionUsageRecordJson {
         this.unitUsageRecords = unitUsageRecords;
     }
 
-    public String getSubscriptionId() {
+    public UUID getSubscriptionId() {
         return subscriptionId;
     }
 
@@ -63,6 +65,7 @@ public class SubscriptionUsageRecordJson {
         return trackingId;
     }
 
+    @ApiModel(value="UnitUsageRecord")
     public static class UnitUsageRecordJson {
 
         private final String unitType;
@@ -94,6 +97,7 @@ public class SubscriptionUsageRecordJson {
         }
     }
 
+    @ApiModel(value="UsageRecord")
     public static class UsageRecordJson {
 
         private final LocalDate recordDate;
@@ -126,7 +130,7 @@ public class SubscriptionUsageRecordJson {
                 return input.toUnitUsageRecord();
             }
         }));
-        final SubscriptionUsageRecord result = new SubscriptionUsageRecord(UUID.fromString(subscriptionId), trackingId, tmp);
+        final SubscriptionUsageRecord result = new SubscriptionUsageRecord(subscriptionId, trackingId, tmp);
         return result;
     }
 }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagDefinitionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagDefinitionJson.java
index 779931c..687173d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagDefinitionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagDefinitionJson.java
@@ -18,6 +18,7 @@ package org.killbill.billing.jaxrs.json;
 
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -31,12 +32,13 @@ import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="TagDefinition")
 public class TagDefinitionJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String id;
+    private final UUID id;
     private final Boolean isControlTag;
     @ApiModelProperty(required = true)
     private final String name;
@@ -45,7 +47,7 @@ public class TagDefinitionJson extends JsonBase {
     private final Set<String> applicableObjectTypes;
 
     @JsonCreator
-    public TagDefinitionJson(@JsonProperty("id") final String id,
+    public TagDefinitionJson(@JsonProperty("id") final UUID id,
                              @JsonProperty("isControlTag") final Boolean isControlTag,
                              @JsonProperty("name") final String name,
                              @JsonProperty("description") @Nullable final String description,
@@ -60,7 +62,7 @@ public class TagDefinitionJson extends JsonBase {
     }
 
     public TagDefinitionJson(final TagDefinition tagDefinition, @Nullable final List<AuditLog> auditLogs) {
-        this(tagDefinition.getId().toString(),
+        this(tagDefinition.getId(),
              tagDefinition.isControlTag(),
              tagDefinition.getName(),
              tagDefinition.getDescription(),
@@ -77,7 +79,7 @@ public class TagDefinitionJson extends JsonBase {
              toAuditLogJson(auditLogs));
     }
 
-    public String getId() {
+    public UUID getId() {
         return id;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagJson.java
index 2b4f729..67681d1 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TagJson.java
@@ -17,6 +17,7 @@
 package org.killbill.billing.jaxrs.json;
 
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -27,25 +28,24 @@ import org.killbill.billing.util.tag.TagDefinition;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Tag")
 public class TagJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String tagId;
+    private final UUID tagId;
     @ApiModelProperty(dataType = "org.killbill.billing.ObjectType")
     private final ObjectType objectType;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String objectId;
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String tagDefinitionId;
+    private final UUID objectId;
+    private final UUID tagDefinitionId;
     private final String tagDefinitionName;
 
     @JsonCreator
-    public TagJson(@JsonProperty("tagId") final String tagId,
+    public TagJson(@JsonProperty("tagId") final UUID tagId,
                    @JsonProperty("objectType") final ObjectType objectType,
-                   @JsonProperty("objectId") final String objectId,
-                   @JsonProperty("tagDefinitionId") final String tagDefinitionId,
+                   @JsonProperty("objectId") final UUID objectId,
+                   @JsonProperty("tagDefinitionId") final UUID tagDefinitionId,
                    @JsonProperty("tagDefinitionName") final String tagDefinitionName,
                    @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
@@ -57,10 +57,10 @@ public class TagJson extends JsonBase {
     }
 
     public TagJson(final Tag tag, final TagDefinition tagDefinition, @Nullable final List<AuditLog> auditLogs) {
-        this(tag.getId().toString(), tag.getObjectType(), tag.getObjectId().toString(), tagDefinition.getId().toString(), tagDefinition.getName(), toAuditLogJson(auditLogs));
+        this(tag.getId(), tag.getObjectType(), tag.getObjectId(), tagDefinition.getId(), tagDefinition.getName(), toAuditLogJson(auditLogs));
     }
 
-    public String getTagId() {
+    public UUID getTagId() {
         return tagId;
     }
 
@@ -68,7 +68,7 @@ public class TagJson extends JsonBase {
         return objectType;
     }
 
-    public String getTagDefinitionId() {
+    public UUID getTagDefinitionId() {
         return tagDefinitionId;
     }
 
@@ -76,7 +76,7 @@ public class TagJson extends JsonBase {
         return tagDefinitionName;
     }
 
-    public String getObjectId() {
+    public UUID getObjectId() {
         return objectId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantJson.java
index c6273b2..615ccf0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantJson.java
@@ -16,17 +16,20 @@
 
 package org.killbill.billing.jaxrs.json;
 
+import java.util.UUID;
+
 import org.killbill.billing.tenant.api.Tenant;
 import org.killbill.billing.tenant.api.TenantData;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="Tenant")
 public class TenantJson extends JsonBase {
 
-    @ApiModelProperty(dataType = "java.util.UUID")
-    private final String tenantId;
+    private final UUID tenantId;
     private final String externalKey;
     @ApiModelProperty(required = true)
     private final String apiKey;
@@ -34,7 +37,7 @@ public class TenantJson extends JsonBase {
     private final String apiSecret;
 
     @JsonCreator
-    public TenantJson(@JsonProperty("tenantId") final String tenantId,
+    public TenantJson(@JsonProperty("tenantId") final UUID tenantId,
                       @JsonProperty("externalKey") final String externalKey,
                       @JsonProperty("apiKey") final String apiKey,
                       @JsonProperty("apiSecret") final String apiSecret) {
@@ -45,7 +48,7 @@ public class TenantJson extends JsonBase {
     }
 
     public TenantJson(final Tenant tenant) {
-        this(tenant.getId().toString(), tenant.getExternalKey(), tenant.getApiKey(), tenant.getApiSecret());
+        this(tenant.getId(), tenant.getExternalKey(), tenant.getApiKey(), tenant.getApiSecret());
     }
 
     public TenantData toTenantData() {
@@ -67,7 +70,7 @@ public class TenantJson extends JsonBase {
         };
     }
 
-    public String getTenantId() {
+    public UUID getTenantId() {
         return tenantId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantKeyJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantKeyJson.java
index f3d3b3d..c1a38e0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantKeyJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TenantKeyJson.java
@@ -20,7 +20,9 @@ import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="TenantKey")
 public class TenantKeyJson {
 
     private final String key;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TierPriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TierPriceOverrideJson.java
index c60c499..7e3f8d2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TierPriceOverrideJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/TierPriceOverrideJson.java
@@ -21,7 +21,9 @@ import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="TierPriceOverride")
 public class TierPriceOverrideJson {
 
     private final List<BlockPriceOverrideJson> blockPriceOverrides;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UsagePriceOverrideJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UsagePriceOverrideJson.java
index bbf1a50..9a2ea42 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UsagePriceOverrideJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UsagePriceOverrideJson.java
@@ -27,7 +27,9 @@ import org.killbill.billing.catalog.api.UsageType;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 
+@ApiModel(value="UsagePriceOverride")
 public class UsagePriceOverrideJson {
 
     private final String usageName;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UserRolesJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UserRolesJson.java
index 7cdf4fd..16c6c54 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UserRolesJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/UserRolesJson.java
@@ -21,8 +21,10 @@ import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+@ApiModel(value="UserRoles")
 public class UserRolesJson {
 
     @ApiModelProperty(required = true)
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 29475d4..23aa22f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -139,14 +139,17 @@ import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.Authorization;
+import io.swagger.annotations.BasicAuthDefinition;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.ACCOUNTS_PATH)
-@Api(value = JaxrsResource.ACCOUNTS_PATH, description = "Operations on accounts")
+@Api(value = JaxrsResource.ACCOUNTS_PATH, description = "Operations on accounts", tags="Account")
 public class AccountResource extends JaxRsResourceBase {
 
     private static final String ID_PARAM_NAME = "accountId";
@@ -192,12 +195,11 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve an account by id", response = AccountJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getAccount(@PathParam("accountId") final String accountIdStr,
+    public Response getAccount(@PathParam("accountId") final UUID accountId,
                                @QueryParam(QUERY_ACCOUNT_WITH_BALANCE) @DefaultValue("false") final Boolean accountWithBalance,
                                @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA,
                                @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
         final Account account = accountUserApi.getAccountById(accountId, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(account.getId(), auditMode.getLevel(), tenantContext);
@@ -272,12 +274,11 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve bundles for account", response = BundleJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getAccountBundles(@PathParam("accountId") final String accountIdStr,
+    public Response getAccountBundles(@PathParam("accountId") final UUID accountId,
                                       @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
                                       @QueryParam(QUERY_BUNDLES_FILTER) final String bundlesFilter,
                                       @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, SubscriptionApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
 
         final Account account = accountUserApi.getAccountById(accountId, tenantContext);
@@ -322,7 +323,7 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve an account by external key", response = AccountJson.class)
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Account not found")})
-    public Response getAccountByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
+    public Response getAccountByKey(@ApiParam(required=true) @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
                                     @QueryParam(QUERY_ACCOUNT_WITH_BALANCE) @DefaultValue("false") final Boolean accountWithBalance,
                                     @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@@ -376,7 +377,7 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Update account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account data supplied")})
     public Response updateAccount(final AccountJson json,
-                                  @PathParam("accountId") final String accountIdStr,
+                                  @PathParam("accountId") final UUID accountId,
                                   @QueryParam(QUERY_ACCOUNT_TREAT_NULL_AS_RESET) @DefaultValue("false") final Boolean treatNullValueAsReset,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
@@ -384,14 +385,13 @@ public class AccountResource extends JaxRsResourceBase {
                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
         verifyNonNullOrEmpty(json, "AccountJson body should be specified");
 
-        final UUID accountId = UUID.fromString(accountIdStr);
         final Account data = json.toAccount(accountId);
         if (treatNullValueAsReset) {
             accountUserApi.updateAccount(data, context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request));
         } else {
             accountUserApi.updateAccount(accountId, data, context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request));
         }
-        return getAccount(accountIdStr, false, false, new AuditMode(AuditLevel.NONE.toString()), request);
+        return getAccount(accountId, false, false, new AuditMode(AuditLevel.NONE.toString()), request);
     }
 
 
@@ -401,7 +401,7 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Close account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response closeAccount(@PathParam(QUERY_ACCOUNT_ID) final String accountIdStr,
+    public Response closeAccount(@PathParam("accountId") final UUID accountId,
                                  @QueryParam(QUERY_CANCEL_ALL_SUBSCRIPTIONS) @DefaultValue("false") final Boolean cancelAllSubscriptions,
                                  @QueryParam(QUERY_WRITE_OFF_UNPAID_INVOICES) @DefaultValue("false") final Boolean writeOffUnpaidInvoices,
                                  @QueryParam(QUERY_ITEM_ADJUST_UNPAID_INVOICES) @DefaultValue("false") final Boolean itemAdjustUnpaidInvoices,
@@ -410,7 +410,6 @@ public class AccountResource extends JaxRsResourceBase {
                                  @HeaderParam(HDR_COMMENT) final String comment,
                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, EntitlementApiException, InvoiceApiException, TagApiException {
 
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         if (cancelAllSubscriptions) {
@@ -456,8 +455,8 @@ public class AccountResource extends JaxRsResourceBase {
             }
         }
 
-        final BlockingStateJson blockingState = new BlockingStateJson(accountIdStr, "CLOSE_ACCOUNT", "account-service", true, false, false, null, BlockingStateType.ACCOUNT, null);
-        addBlockingState(blockingState, accountIdStr, BlockingStateType.ACCOUNT, null, ImmutableList.<String>of(), createdBy, reason, comment, request);
+        final BlockingStateJson blockingState = new BlockingStateJson(accountId, "CLOSE_ACCOUNT", "account-service", true, false, false, null, BlockingStateType.ACCOUNT, null);
+        addBlockingState(blockingState, accountId, BlockingStateType.ACCOUNT, null, ImmutableList.<String>of(), createdBy, reason, comment, request);
 
         return Response.status(Status.OK).build();
     }
@@ -469,12 +468,11 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account timeline", response = AccountTimelineJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getAccountTimeline(@PathParam("accountId") final String accountIdStr,
+    public Response getAccountTimeline(@PathParam("accountId") final UUID accountId,
                                        @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                        @QueryParam(QUERY_PARALLEL) @DefaultValue("false") final Boolean parallel,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException, SubscriptionApiException, InvoiceApiException, CatalogApiException {
 
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
 
         final Account account = accountUserApi.getAccountById(accountId, tenantContext);
@@ -623,11 +621,10 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account email notification", response = InvoiceEmailJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getEmailNotificationsForAccount(@PathParam("accountId") final String accountIdStr,
+    public Response getEmailNotificationsForAccount(@PathParam("accountId") final UUID accountId,
                                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final Account account = accountUserApi.getAccountById(accountId, context.createTenantContextWithAccountId(accountId, request));
-        final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountIdStr, account.isNotifiedForInvoices());
+        final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountId, account.isNotifiedForInvoices());
 
         return Response.status(Status.OK).entity(invoiceEmailJson).build();
     }
@@ -641,14 +638,12 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
     public Response setEmailNotificationsForAccount(final InvoiceEmailJson json,
-                                                    @PathParam("accountId") final String accountIdStr,
+                                                    @PathParam("accountId") final UUID accountId,
                                                     @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                     @HeaderParam(HDR_REASON) final String reason,
                                                     @HeaderParam(HDR_COMMENT) final String comment,
                                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
         verifyNonNullOrEmpty(json, "InvoiceEmailJson body should be specified");
-
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(accountId, callContext);
@@ -670,15 +665,12 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Rebalance account CBA")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response rebalanceExistingCBAOnAccount(@PathParam("accountId") final String accountIdStr,
+    public Response rebalanceExistingCBAOnAccount(@PathParam("accountId") final UUID accountId,
                                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                   @HeaderParam(HDR_REASON) final String reason,
                                                   @HeaderParam(HDR_COMMENT) final String comment,
                                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
-
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
-
         invoiceApi.consumeExstingCBAOnAccountWithUnpaidInvoices(accountId, callContext);
         return Response.status(Status.OK).build();
     }
@@ -695,15 +687,13 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account invoices", response = InvoiceJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getInvoices(@PathParam("accountId") final String accountIdStr,
+    public Response getInvoices(@PathParam("accountId") final UUID accountId,
                                 @QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems,
                                 @QueryParam(QUERY_WITH_MIGRATION_INVOICES) @DefaultValue("false") final boolean withMigrationInvoices,
                                 @QueryParam(QUERY_UNPAID_INVOICES_ONLY) @DefaultValue("false") final boolean unpaidInvoicesOnly,
                                 @QueryParam(QUERY_INCLUDE_VOIDED_INVOICES) @DefaultValue("false") final boolean includeVoidedInvoices,
                                 @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
-
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
 
         // Verify the account exists
@@ -735,14 +725,13 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account invoice payments", response = InvoicePaymentJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getInvoicePayments(@PathParam("accountId") final String accountIdStr,
+    public Response getInvoicePayments(@PathParam("accountId") final UUID accountId,
                                        @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                        @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                        @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
                                        @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
         final Account account = accountUserApi.getAccountById(accountId, tenantContext);
         final List<Payment> payments = paymentApi.getAccountPayments(account.getId(), withPluginInfo, withAttempts, pluginProperties, tenantContext);
@@ -764,7 +753,7 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Trigger a payment for all unpaid invoices")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response payAllInvoices(@PathParam("accountId") final String accountIdStr,
+    public Response payAllInvoices(@PathParam("accountId") final UUID accountId,
                                    @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
                                    @QueryParam(QUERY_PAYMENT_AMOUNT) final BigDecimal paymentAmount,
                                    @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
@@ -774,7 +763,6 @@ public class AccountResource extends JaxRsResourceBase {
                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException, InvoiceApiException {
 
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(accountId, callContext);
@@ -819,7 +807,7 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
     public Response createPaymentMethod(final PaymentMethodJson json,
-                                        @PathParam("accountId") final String accountIdStr,
+                                        @PathParam("accountId") final UUID accountId,
                                         @QueryParam(QUERY_PAYMENT_METHOD_IS_DEFAULT) @DefaultValue("false") final Boolean isDefault,
                                         @QueryParam(QUERY_PAY_ALL_UNPAID_INVOICES) @DefaultValue("false") final Boolean payAllUnpaidInvoices,
                                         @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
@@ -831,13 +819,10 @@ public class AccountResource extends JaxRsResourceBase {
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
         verifyNonNullOrEmpty(json, "PaymentMethodJson body should be specified");
         verifyNonNullOrEmpty(json.getPluginName(), "PaymentMethodJson pluginName should be specified");
-
-        final UUID accountId = UUID.fromString(accountIdStr);
-
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
-        final PaymentMethod data = json.toPaymentMethod(accountIdStr);
+        final PaymentMethod data = json.toPaymentMethod(accountId);
         final Account account = accountUserApi.getAccountById(data.getAccountId(), callContext);
 
         final boolean hasDefaultPaymentMethod = account.getPaymentMethodId() != null || isDefault;
@@ -865,14 +850,13 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account payment methods", response = PaymentMethodJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getPaymentMethods(@PathParam("accountId") final String accountIdStr,
+    public Response getPaymentMethods(@PathParam("accountId") final UUID accountId,
                                       @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                       @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                       @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                                       @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
 
         final Account account = accountUserApi.getAccountById(accountId, tenantContext);
@@ -895,7 +879,7 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Refresh account payment methods")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response refreshPaymentMethods(@PathParam("accountId") final String accountIdStr,
+    public Response refreshPaymentMethods(@PathParam("accountId") final UUID accountId,
                                           @QueryParam(QUERY_PAYMENT_PLUGIN_NAME) final String pluginName,
                                           @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                           @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -903,7 +887,6 @@ public class AccountResource extends JaxRsResourceBase {
                                           @HeaderParam(HDR_COMMENT) final String comment,
                                           @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(accountId, callContext);
@@ -925,8 +908,8 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Set the default payment method")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id or payment method id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response setDefaultPaymentMethod(@PathParam("accountId") final String accountIdStr,
-                                            @PathParam("paymentMethodId") final String paymentMethodId,
+    public Response setDefaultPaymentMethod(@PathParam("accountId") final UUID accountId,
+                                            @PathParam("paymentMethodId") final UUID paymentMethodId,
                                             @QueryParam(QUERY_PAY_ALL_UNPAID_INVOICES) @DefaultValue("false") final Boolean payAllUnpaidInvoices,
                                             @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                             @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -934,17 +917,15 @@ public class AccountResource extends JaxRsResourceBase {
                                             @HeaderParam(HDR_COMMENT) final String comment,
                                             @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(accountId, callContext);
-        final UUID newPaymentMethodId = UUID.fromString(paymentMethodId);
-        paymentApi.setDefaultPaymentMethod(account, newPaymentMethodId, pluginProperties, callContext);
+        paymentApi.setDefaultPaymentMethod(account, paymentMethodId, pluginProperties, callContext);
 
         if (payAllUnpaidInvoices) {
             final Collection<Invoice> unpaidInvoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
             for (final Invoice invoice : unpaidInvoices) {
-                createPurchaseForInvoice(account, invoice.getId(), invoice.getBalance(), newPaymentMethodId, false, null, null, pluginProperties, callContext);
+                createPurchaseForInvoice(account, invoice.getId(), invoice.getBalance(), paymentMethodId, false, null, null, pluginProperties, callContext);
             }
         }
         return Response.status(Status.OK).build();
@@ -959,13 +940,12 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve account payments", response = PaymentJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response getPayments(@PathParam("accountId") final String accountIdStr,
+    public Response getPayments(@PathParam("accountId") final UUID accountId,
                                 @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                 @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                 @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                 @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
         final List<Payment> payments = paymentApi.getAccountPayments(accountId, withPluginInfo, withAttempts, pluginProperties, tenantContext);
@@ -994,8 +974,8 @@ public class AccountResource extends JaxRsResourceBase {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response processPaymentByExternalKey(@MetricTag(tag = "type", property = "transactionType") final PaymentTransactionJson json,
-                                                @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
-                                                @QueryParam(QUERY_PAYMENT_METHOD_ID) final String paymentMethodIdStr,
+                                                @ApiParam(required=true)  @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
+                                                @QueryParam(QUERY_PAYMENT_METHOD_ID) final UUID paymentMethodId,
                                                 @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                                 @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -1006,7 +986,7 @@ public class AccountResource extends JaxRsResourceBase {
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
         final Account account = accountUserApi.getAccountByKey(externalKey, callContext);
 
-        return processPayment(json, account, paymentMethodIdStr, paymentControlPluginNames, pluginPropertiesString, uriInfo, callContext, request);
+        return processPayment(json, account, paymentMethodId, paymentControlPluginNames, pluginPropertiesString, uriInfo, callContext, request);
     }
 
     @TimedResource(name = "processPayment")
@@ -1024,8 +1004,8 @@ public class AccountResource extends JaxRsResourceBase {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response processPayment(@MetricTag(tag = "type", property = "transactionType") final PaymentTransactionJson json,
-                                   @PathParam(QUERY_ACCOUNT_ID) final String accountIdStr,
-                                   @QueryParam(QUERY_PAYMENT_METHOD_ID) final String paymentMethodIdStr,
+                                   @PathParam("accountId") final UUID accountId,
+                                   @QueryParam(QUERY_PAYMENT_METHOD_ID) final UUID inputPaymentMethodId,
                                    @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                    @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                    @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -1033,16 +1013,15 @@ public class AccountResource extends JaxRsResourceBase {
                                    @HeaderParam(HDR_COMMENT) final String comment,
                                    @javax.ws.rs.core.Context final UriInfo uriInfo,
                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
         final Account account = accountUserApi.getAccountById(accountId, callContext);
 
-        return processPayment(json, account, paymentMethodIdStr, paymentControlPluginNames, pluginPropertiesString, uriInfo, callContext, request);
+        return processPayment(json, account, inputPaymentMethodId, paymentControlPluginNames, pluginPropertiesString, uriInfo, callContext, request);
     }
 
     private Response processPayment(final PaymentTransactionJson json,
                                     final Account account,
-                                    final String paymentMethodIdStr,
+                                    final UUID inputPaymentMethodId,
                                     final List<String> paymentControlPluginNames,
                                     final List<String> pluginPropertiesString,
                                     final UriInfo uriInfo,
@@ -1054,7 +1033,7 @@ public class AccountResource extends JaxRsResourceBase {
 
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final Currency currency = json.getCurrency() == null ? account.getCurrency() : Currency.valueOf(json.getCurrency());
-        final UUID paymentId = json.getPaymentId() == null ? null : UUID.fromString(json.getPaymentId());
+        final UUID paymentId = json.getPaymentId();
 
         //
         // If paymentId was specified, it means we are attempting a payment completion. The preferred way is to use the PaymentResource
@@ -1075,7 +1054,7 @@ public class AccountResource extends JaxRsResourceBase {
 
             paymentMethodId = initialPayment.getPaymentMethodId();
         } else {
-            paymentMethodId = paymentMethodIdStr == null ? account.getPaymentMethodId() : UUID.fromString(paymentMethodIdStr);
+            paymentMethodId = inputPaymentMethodId == null ? account.getPaymentMethodId() : inputPaymentMethodId;
         }
         validatePaymentMethodForAccount(account.getId(), paymentMethodId, callContext);
 
@@ -1115,9 +1094,8 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve overdue state for account", response = OverdueStateJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getOverdueAccount(@PathParam("accountId") final String accountIdStr,
+    public Response getOverdueAccount(@PathParam("accountId") final UUID accountId,
                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, OverdueException, OverdueApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
 
         final Account account = accountUserApi.getAccountById(accountId, tenantContext);
@@ -1137,13 +1115,12 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve blocking states for account", response = BlockingStateJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response getBlockingStates(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response getBlockingStates(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                       @QueryParam(QUERY_BLOCKING_STATE_TYPES) final List<BlockingStateType> typeFilter,
                                       @QueryParam(QUERY_BLOCKING_STATE_SVCS) final List<String> svcsFilter,
                                       @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException {
 
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = this.context.createTenantContextWithAccountId(accountId, request);
         final Iterable<BlockingState> blockingStates = subscriptionApi.getBlockingStates(accountId, typeFilter, svcsFilter, OrderingType.ASCENDING, SubscriptionApi.ALL_EVENTS, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(accountId, auditMode.getLevel(), tenantContext);
@@ -1166,7 +1143,7 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
     public Response addAccountBlockingState(final BlockingStateJson json,
-                                           @PathParam(ID_PARAM_NAME) final String id,
+                                           @PathParam(ID_PARAM_NAME) final UUID id,
                                            @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                            @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                            @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -1187,10 +1164,9 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve account custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        final UUID accountId = UUID.fromString(accountIdStr);
         return super.getCustomFields(accountId, auditMode, context.createTenantContextWithAccountId(accountId, request));
     }
 
@@ -1201,12 +1177,10 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account customFields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getAllCustomFields(@PathParam(ID_PARAM_NAME) final String accountIdString,
+    public Response getAllCustomFields(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                        @QueryParam(QUERY_OBJECT_TYPE) final ObjectType objectType,
                                        @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) {
-        final UUID accountId = UUID.fromString(accountIdString);
-
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
         final List<CustomField> customFields = objectType != null ?
                                                customFieldUserApi.getCustomFieldsForAccountType(accountId, objectType, tenantContext) :
@@ -1221,14 +1195,13 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         return super.createCustomFields(accountId, customFields, context.createCallContextWithAccountId(accountId, createdBy, reason,
                                                                                                         comment, request), uriInfo, request);
     }
@@ -1241,13 +1214,12 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         return super.modifyCustomFields(accountId, customFields, context.createCallContextWithAccountId(accountId, createdBy, reason,
                                                                                                         comment, request));
     }
@@ -1259,13 +1231,12 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         return super.deleteCustomFields(accountId, customFieldList,
                                         context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request));
     }
@@ -1281,11 +1252,10 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID accountId,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         return super.getTags(accountId, accountId, auditMode, includedDeleted, context.createTenantContextWithAccountId(accountId, request));
     }
 
@@ -1296,12 +1266,11 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve account tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getAllTags(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response getAllTags(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                @QueryParam(QUERY_OBJECT_TYPE) final ObjectType objectType,
                                @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
         final List<Tag> tags = objectType != null ?
                                tagUserApi.getTagsForAccountType(accountId, objectType, includedDeleted, tenantContext) :
@@ -1315,14 +1284,13 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         return super.createTags(accountId, tagList, uriInfo,
                                 context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request), request);
     }
@@ -1334,13 +1302,12 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied or account does not have a default payment method (AUTO_PAY_OFF tag only)")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException, AccountApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         // Look if there is an AUTO_PAY_OFF for that account and check if the account has a default paymentMethod
@@ -1373,14 +1340,13 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve an account emails", response = AccountEmailJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response getEmails(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response getEmails(@PathParam(ID_PARAM_NAME) final UUID accountId,
                               @javax.ws.rs.core.Context final HttpServletRequest request) {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final List<AccountEmail> emails = accountUserApi.getEmails(accountId, context.createTenantContextWithAccountId(accountId, request));
 
         final List<AccountEmailJson> emailsJson = new ArrayList<AccountEmailJson>();
         for (final AccountEmail email : emails) {
-            emailsJson.add(new AccountEmailJson(email.getAccountId().toString(), email.getEmail()));
+            emailsJson.add(new AccountEmailJson(email.getAccountId(), email.getEmail()));
         }
         return Response.status(Status.OK).entity(emailsJson).build();
     }
@@ -1394,7 +1360,7 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
     public Response addEmail(final AccountEmailJson json,
-                             @PathParam(ID_PARAM_NAME) final String id,
+                             @PathParam(ID_PARAM_NAME) final UUID accountId,
                              @HeaderParam(HDR_CREATED_BY) final String createdBy,
                              @HeaderParam(HDR_REASON) final String reason,
                              @HeaderParam(HDR_COMMENT) final String comment,
@@ -1402,8 +1368,6 @@ public class AccountResource extends JaxRsResourceBase {
                              @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException {
         verifyNonNullOrEmpty(json, "AccountEmailJson body should be specified");
         verifyNonNullOrEmpty(json.getEmail(), "AccountEmailJson email needs to be set");
-
-        final UUID accountId = UUID.fromString(id);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
 
@@ -1433,18 +1397,16 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Delete email from account")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied")})
-    public Response removeEmail(@PathParam(ID_PARAM_NAME) final String accountIdStr,
+    public Response removeEmail(@PathParam(ID_PARAM_NAME) final UUID accountId,
                                 @PathParam("email") final String email,
                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                 @HeaderParam(HDR_REASON) final String reason,
                                 @HeaderParam(HDR_COMMENT) final String comment,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) {
-        final UUID accountId = UUID.fromString(accountIdStr);
-
         final List<AccountEmail> emails = accountUserApi.getEmails(accountId, context.createTenantContextWithAccountId(accountId, request));
         for (final AccountEmail cur : emails) {
             if (cur.getEmail().equals(email)) {
-                final AccountEmailJson accountEmailJson = new AccountEmailJson(accountId.toString(), email);
+                final AccountEmailJson accountEmailJson = new AccountEmailJson(accountId, email);
                 final AccountEmail accountEmail = accountEmailJson.toAccountEmail(cur.getId());
                 accountUserApi.removeEmail(accountId, accountEmail, context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request));
             }
@@ -1468,13 +1430,12 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "List children accounts", response = AccountJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid parent account id supplied"),
                            @ApiResponse(code = 404, message = "Parent Account not found")})
-    public Response getChildrenAccounts(@PathParam("accountId") final String parentAccountIdStr,
+    public Response getChildrenAccounts(@PathParam("accountId") final UUID parentAccountId,
                                         @QueryParam(QUERY_ACCOUNT_WITH_BALANCE) @DefaultValue("false") final Boolean accountWithBalance,
                                         @QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA,
                                         @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
 
-        final UUID parentAccountId = UUID.fromString(parentAccountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(parentAccountId, request);
         final List<Account> accounts = accountUserApi.getChildrenAccounts(parentAccountId, tenantContext);
 
@@ -1494,14 +1455,13 @@ public class AccountResource extends JaxRsResourceBase {
     @ApiOperation(value = "Move a given child credit to the parent level")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Account does not have credit"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response transferChildCreditToParent(@PathParam("childAccountId") final String childAccountIdStr,
+    public Response transferChildCreditToParent(@PathParam("childAccountId") final UUID childAccountId,
                                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                 @HeaderParam(HDR_REASON) final String reason,
                                                 @HeaderParam(HDR_COMMENT) final String comment,
                                                 @javax.ws.rs.core.Context final HttpServletRequest request,
                                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws InvoiceApiException {
 
-        final UUID childAccountId = UUID.fromString(childAccountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(childAccountId, createdBy, reason, comment, request);
 
         invoiceApi.transferChildCreditToParent(childAccountId, callContext);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
index f439655..443cba2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
@@ -105,7 +105,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.ADMIN_PATH)
-@Api(value = JaxrsResource.ADMIN_PATH, description = "Admin operations (will require special privileges)")
+@Api(value = JaxrsResource.ADMIN_PATH, description = "Admin operations (will require special privileges)", tags="Admin")
 public class AdminResource extends JaxRsResourceBase {
 
     private static final String OK = "OK";
@@ -150,9 +150,9 @@ public class AdminResource extends JaxRsResourceBase {
     @GET
     @Path("/queues")
     @Produces(APPLICATION_JSON)
-    @ApiOperation(value = "Get queues entries", response = Response.class)
+    @ApiOperation(value = "Get queues entries", response = Response.class, hidden=true)
     @ApiResponses(value = {})
-    public Response getQueueEntries(@QueryParam("accountId") final String accountIdStr,
+    public Response getQueueEntries(@QueryParam("accountId") final UUID accountId,
                                     @QueryParam("queueName") final String queueName,
                                     @QueryParam("serviceName") final String serviceName,
                                     @QueryParam("withHistory") @DefaultValue("true") final Boolean withHistory,
@@ -164,7 +164,7 @@ public class AdminResource extends JaxRsResourceBase {
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Long tenantRecordId = recordIdApi.getRecordId(tenantContext.getTenantId(), ObjectType.TENANT, tenantContext);
-        final Long accountRecordId = Strings.isNullOrEmpty(accountIdStr) ? null : recordIdApi.getRecordId(UUID.fromString(accountIdStr), ObjectType.ACCOUNT, tenantContext);
+        final Long accountRecordId = accountId == null ? null : recordIdApi.getRecordId(accountId, ObjectType.ACCOUNT, tenantContext);
 
         // Limit search results by default
         final DateTime minDate = Strings.isNullOrEmpty(minDateOrNull) ? clock.getUTCNow().minusDays(2) : DATE_TIME_FORMATTER.parseDateTime(minDateOrNull).toDateTime(DateTimeZone.UTC);
@@ -233,8 +233,8 @@ public class AdminResource extends JaxRsResourceBase {
     @ApiOperation(value = "Update existing paymentTransaction and associated payment state")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account data supplied")})
     public Response updatePaymentTransactionState(final AdminPaymentJson json,
-                                                  @PathParam("paymentId") final String paymentIdStr,
-                                                  @PathParam("paymentTransactionId") final String paymentTransactionIdStr,
+                                                  @PathParam("paymentId") final UUID paymentId,
+                                                  @PathParam("paymentTransactionId") final UUID paymentTransactionId,
                                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                   @HeaderParam(HDR_REASON) final String reason,
                                                   @HeaderParam(HDR_COMMENT) final String comment,
@@ -242,10 +242,7 @@ public class AdminResource extends JaxRsResourceBase {
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final Payment payment = paymentApi.getPayment(UUID.fromString(paymentIdStr), false, false, ImmutableList.<PluginProperty>of(), callContext);
-
-        final UUID paymentTransactionId = UUID.fromString(paymentTransactionIdStr);
-
+        final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final PaymentTransaction paymentTransaction = Iterables.tryFind(payment.getTransactions(), new Predicate<PaymentTransaction>() {
             @Override
             public boolean apply(final PaymentTransaction input) {
@@ -349,16 +346,15 @@ public class AdminResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Invalidates Caches per account level")
     @ApiResponses(value = {})
-    public Response invalidatesCacheByAccount(@PathParam("accountId") final String accountIdStr,
+    public Response invalidatesCacheByAccount(@PathParam("accountId") final UUID accountId,
                                               @javax.ws.rs.core.Context final HttpServletRequest request) {
 
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
         final Long accountRecordId = recordIdApi.getRecordId(accountId, ObjectType.ACCOUNT, tenantContext);
 
         // clear account-record-id cache by accountId (note: String!)
         final CacheController<String, Long> accountRecordIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID);
-        accountRecordIdCacheController.remove(accountIdStr);
+        accountRecordIdCacheController.remove(accountId.toString());
 
         // clear account-immutable cache by account record id
         final CacheController<Long, ImmutableAccountData> accountImmutableCacheController = cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_IMMUTABLE);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index cff17bc..476d72a 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -80,13 +80,14 @@ import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.BUNDLES_PATH)
-@Api(value = JaxrsResource.BUNDLES_PATH, description = "Operations on bundles")
+@Api(value = JaxrsResource.BUNDLES_PATH, description = "Operations on bundles", tags="Bundle")
 public class BundleResource extends JaxRsResourceBase {
 
     private static final String ID_PARAM_NAME = "bundleId";
@@ -117,12 +118,11 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve a bundle by id", response = BundleJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
-    public Response getBundle(@PathParam("bundleId") final String bundleId,
+    public Response getBundle(@PathParam("bundleId") final UUID bundleId,
                               @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                               @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
-        final UUID id = UUID.fromString(bundleId);
         final TenantContext tenantContext = this.context.createTenantContextNoAccountId(request);
-        final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(id, tenantContext);
+        final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, tenantContext);
         final Account account = accountUserApi.getAccountById(bundle.getAccountId(), tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(bundle.getAccountId(), auditMode.getLevel(), tenantContext);
         final BundleJson json = new BundleJson(bundle, account.getCurrency(), accountAuditLogs);
@@ -134,7 +134,7 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve a bundle by external key", response = BundleJson.class)
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Bundle not found")})
-    public Response getBundleByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
+    public Response getBundleByKey(@ApiParam(required=true) @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
                                    @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                                    @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
@@ -235,7 +235,7 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiOperation(value = "Pause a bundle")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
-    public Response pauseBundle(@PathParam(ID_PARAM_NAME) final String id,
+    public Response pauseBundle(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                 @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                 @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -244,7 +244,6 @@ public class BundleResource extends JaxRsResourceBase {
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, EntitlementApiException, AccountApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID bundleId = UUID.fromString(id);
         final LocalDate inputLocalDate = toLocalDate(requestedDate);
         entitlementApi.pause(bundleId, inputLocalDate, pluginProperties, callContext);
         return Response.status(Status.OK).build();
@@ -258,7 +257,7 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiOperation(value = "Resume a bundle")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
-    public Response resumeBundle(@PathParam(ID_PARAM_NAME) final String id,
+    public Response resumeBundle(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                  @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                  @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -267,7 +266,6 @@ public class BundleResource extends JaxRsResourceBase {
                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, EntitlementApiException, AccountApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID bundleId = UUID.fromString(id);
         final LocalDate inputLocalDate = toLocalDate(requestedDate);
         entitlementApi.resume(bundleId, inputLocalDate, pluginProperties, callContext);
         return Response.status(Status.OK).build();
@@ -281,7 +279,7 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
     public Response addBundleBlockingState(final BlockingStateJson json,
-                                           @PathParam(ID_PARAM_NAME) final String id,
+                                           @PathParam(ID_PARAM_NAME) final UUID id,
                                            @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                            @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                            @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -299,10 +297,10 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve bundle custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(id), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(bundleId, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @TimedResource
@@ -312,14 +310,14 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to bundle")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(id), customFields,
+        return super.createCustomFields(bundleId, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -330,13 +328,13 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to bundle")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(id), customFields,
+        return super.modifyCustomFields(bundleId, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -350,13 +348,13 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from bundle")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(id), customFieldList,
+        return super.deleteCustomFields(bundleId, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -367,11 +365,10 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve bundle tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String bundleIdString,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, SubscriptionApiException {
-        final UUID bundleId = UUID.fromString(bundleIdString);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, tenantContext);
         return super.getTags(bundle.getAccountId(), bundleId, auditMode, includedDeleted, tenantContext);
@@ -386,7 +383,7 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id, requested date or policy supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
     public Response transferBundle(final BundleJson json,
-                                   @PathParam(ID_PARAM_NAME) final String id,
+                                   @PathParam(ID_PARAM_NAME) final UUID bundleId,
                                    @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                    @QueryParam(QUERY_BILLING_POLICY) @DefaultValue("END_OF_TERM") final String policyString,
                                    @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
@@ -402,12 +399,10 @@ public class BundleResource extends JaxRsResourceBase {
         final BillingActionPolicy policy = BillingActionPolicy.valueOf(policyString.toUpperCase());
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID bundleId = UUID.fromString(id);
-
         final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(bundleId, callContext);
         final LocalDate inputLocalDate = toLocalDate(requestedDate);
 
-        final UUID newBundleId = entitlementApi.transferEntitlementsOverrideBillingPolicy(bundle.getAccountId(), UUID.fromString(json.getAccountId()), bundle.getExternalKey(), inputLocalDate, policy, pluginProperties, callContext);
+        final UUID newBundleId = entitlementApi.transferEntitlementsOverrideBillingPolicy(bundle.getAccountId(), json.getAccountId(), bundle.getExternalKey(), inputLocalDate, policy, pluginProperties, callContext);
         return uriBuilder.buildResponse(uriInfo, BundleResource.class, "getBundle", newBundleId, request);
     }
 
@@ -420,7 +415,7 @@ public class BundleResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid argumnent supplied"),
                            @ApiResponse(code = 404, message = "Bundle not found")})
     public Response renameExternalKey(final BundleJson json,
-                                      @PathParam(ID_PARAM_NAME) final String id,
+                                      @PathParam(ID_PARAM_NAME) final UUID bundleId,
                                       /* @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, */
                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                       @HeaderParam(HDR_REASON) final String reason,
@@ -431,8 +426,6 @@ public class BundleResource extends JaxRsResourceBase {
         verifyNonNullOrEmpty(json, "BundleJson body should be specified");
         verifyNonNullOrEmpty(json.getExternalKey(), "BundleJson externalKey needs to be set");
 
-        final UUID bundleId = UUID.fromString(id);
-
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
         subscriptionApi.updateExternalKey(bundleId, json.getExternalKey(), callContext);
         return uriBuilder.buildResponse(uriInfo, BundleResource.class, "getBundle", bundleId, request);
@@ -447,14 +440,14 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to bundle")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.createTags(UUID.fromString(id), tagList, uriInfo,
+        return super.createTags(bundleId, tagList, uriInfo,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request), request);
     }
 
@@ -465,13 +458,13 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from bundle")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID bundleId,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.deleteTags(UUID.fromString(id), tagList,
+        return super.deleteTags(bundleId, tagList,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
index c68ce54..70752e0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
@@ -91,7 +91,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_XML;
 
 @Singleton
 @Path(JaxrsResource.CATALOG_PATH)
-@Api(value = JaxrsResource.CATALOG_PATH, description = "Catalog information")
+@Api(value = JaxrsResource.CATALOG_PATH, description = "Catalog information", tags="Catalog")
 public class CatalogResource extends JaxRsResourceBase {
 
     private final CatalogUserApi catalogUserApi;
@@ -222,12 +222,12 @@ public class CatalogResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve plan for a given subscription and date", response = PlanJson.class)
     @ApiResponses(value = {})
-    public Response getPlanForSubscriptionAndDate(@QueryParam("subscriptionId") final String subscriptionIdString,
+    public Response getPlanForSubscriptionAndDate(@QueryParam("subscriptionId") final UUID subscriptionId,
                                                   @QueryParam("requestedDate") final String requestedDateString,
                                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, CurrencyValueNull {
-        verifyNonNullOrEmpty(subscriptionIdString, "Subscription id needs to be specified");
+        verifyNonNullOrEmpty(subscriptionId, "Subscription id needs to be specified");
 
-        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionIdString, requestedDateString, request);
+        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionId, requestedDateString, request);
         if (lastEventBeforeRequestedDate == null) {
             return Response.status(Status.BAD_REQUEST).entity(String.format("%s is before the subscription start date", requestedDateString)).type("text/plain").build();
         }
@@ -248,12 +248,12 @@ public class CatalogResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve phase for a given subscription and date", response = PhaseJson.class)
     @ApiResponses(value = {})
-    public Response getPhaseForSubscriptionAndDate(@QueryParam("subscriptionId") final String subscriptionIdString,
+    public Response getPhaseForSubscriptionAndDate(@QueryParam("subscriptionId") final UUID subscriptionId,
                                                    @QueryParam("requestedDate") final String requestedDateString,
                                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, CurrencyValueNull {
-        verifyNonNullOrEmpty(subscriptionIdString, "Subscription id needs to be specified");
+        verifyNonNullOrEmpty(subscriptionId, "Subscription id needs to be specified");
 
-        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionIdString, requestedDateString, request);
+        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionId, requestedDateString, request);
         if (lastEventBeforeRequestedDate == null) {
             return Response.status(Status.BAD_REQUEST).entity(String.format("%s is before the subscription start date", requestedDateString)).type("text/plain").build();
         }
@@ -274,12 +274,12 @@ public class CatalogResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve product for a given subscription and date", response = ProductJson.class)
     @ApiResponses(value = {})
-    public Response getProductForSubscriptionAndDate(@QueryParam("subscriptionId") final String subscriptionIdString,
+    public Response getProductForSubscriptionAndDate(@QueryParam("subscriptionId") final UUID subscriptionId,
                                                      @QueryParam("requestedDate") final String requestedDateString,
                                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
-        verifyNonNullOrEmpty(subscriptionIdString, "Subscription id needs to be specified");
+        verifyNonNullOrEmpty(subscriptionId, "Subscription id needs to be specified");
 
-        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionIdString, requestedDateString, request);
+        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionId, requestedDateString, request);
         if (lastEventBeforeRequestedDate == null) {
             return Response.status(Status.BAD_REQUEST).entity(String.format("%s is before the subscription start date", requestedDateString)).type("text/plain").build();
         }
@@ -300,12 +300,12 @@ public class CatalogResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve priceList for a given subscription and date", response = PriceListJson.class)
     @ApiResponses(value = {})
-    public Response getPriceListForSubscriptionAndDate(@QueryParam("subscriptionId") final String subscriptionIdString,
+    public Response getPriceListForSubscriptionAndDate(@QueryParam("subscriptionId") final UUID subscriptionId,
                                                        @QueryParam("requestedDate") final String requestedDateString,
                                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
-        verifyNonNullOrEmpty(subscriptionIdString, "Subscription id needs to be specified");
+        verifyNonNullOrEmpty(subscriptionId, "Subscription id needs to be specified");
 
-        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionIdString, requestedDateString, request);
+        final SubscriptionEvent lastEventBeforeRequestedDate = getLastEventBeforeDate(subscriptionId, requestedDateString, request);
         if (lastEventBeforeRequestedDate == null) {
             return Response.status(Status.BAD_REQUEST).entity(String.format("%s is before the subscription start date", requestedDateString)).type("text/plain").build();
         }
@@ -320,14 +320,14 @@ public class CatalogResource extends JaxRsResourceBase {
         return Response.status(Status.OK).entity(priceListJson).build();
     }
 
-    private SubscriptionEvent getLastEventBeforeDate(final String subscriptionIdString, final String requestedDateString, final HttpServletRequest request) throws SubscriptionApiException {
+    private SubscriptionEvent getLastEventBeforeDate(final UUID subscriptionId, final String requestedDateString, final HttpServletRequest request) throws SubscriptionApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final DateTime requestedDateTime = requestedDateString != null ?
                                            DATE_TIME_FORMATTER.parseDateTime(requestedDateString).toDateTime(DateTimeZone.UTC) :
                                            clock.getUTCNow();
         final LocalDate requestedDate = requestedDateTime.toLocalDate();
 
-        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(UUID.fromString(subscriptionIdString), tenantContext);
+        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(subscriptionId, tenantContext);
         SubscriptionEvent lastEventBeforeRequestedDate = null;
         for (final SubscriptionEvent subscriptionEvent : subscription.getSubscriptionEvents()) {
             if (lastEventBeforeRequestedDate == null) {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
index bc87d1e..f93fd74 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
@@ -65,7 +65,7 @@ public abstract class ComboPaymentResource extends JaxRsResourceBase {
     protected Account getOrCreateAccount(final AccountJson accountJson, final CallContext callContext) throws AccountApiException {
         // Attempt to retrieve by accountId if specified
         if (accountJson.getAccountId() != null) {
-            return accountUserApi.getAccountById(UUID.fromString(accountJson.getAccountId()), callContext);
+            return accountUserApi.getAccountById(accountJson.getAccountId(), callContext);
         }
 
         if (accountJson.getExternalKey() != null) {
@@ -91,7 +91,7 @@ public abstract class ComboPaymentResource extends JaxRsResourceBase {
 
         // If we were specified a paymentMethod id and we find it, we return it
         if (paymentMethodJson.getPaymentMethodId() != null) {
-            final UUID match = UUID.fromString(paymentMethodJson.getPaymentMethodId());
+            final UUID match = paymentMethodJson.getPaymentMethodId();
             if (Iterables.any(accountPaymentMethods, new Predicate<PaymentMethod>() {
                 @Override
                 public boolean apply(final PaymentMethod input) {
@@ -118,7 +118,7 @@ public abstract class ComboPaymentResource extends JaxRsResourceBase {
 
         // Only set as default if this is the first paymentMethod on the account
         final boolean isDefault = accountPaymentMethods.isEmpty();
-        final PaymentMethod paymentData = paymentMethodJson.toPaymentMethod(account.getId().toString());
+        final PaymentMethod paymentData = paymentMethodJson.toPaymentMethod(account.getId());
         return paymentApi.addPaymentMethod(account, paymentMethodJson.getExternalKey(), paymentMethodJson.getPluginName(), isDefault,
                                            paymentData.getPluginDetail(), pluginProperties, callContext);
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
index f816d4e..d560165 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
@@ -62,7 +62,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.CREDITS_PATH)
-@Api(value = JaxrsResource.CREDITS_PATH, description = "Operations on credits")
+@Api(value = JaxrsResource.CREDITS_PATH, description = "Operations on credits", tags="Credit")
 public class CreditResource extends JaxRsResourceBase {
 
     private final InvoiceUserApi invoiceUserApi;
@@ -89,10 +89,10 @@ public class CreditResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve a credit by id", response = CreditJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid credit id supplied"),
                            @ApiResponse(code = 404, message = "Credit not found")})
-    public Response getCredit(@PathParam("creditId") final String creditId,
+    public Response getCredit(@PathParam("creditId") final UUID creditId,
                               @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException, AccountApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId), tenantContext);
+        final InvoiceItem credit = invoiceUserApi.getCreditById(creditId, tenantContext);
         final Invoice invoice = invoiceUserApi.getInvoice(credit.getInvoiceId(), tenantContext);
         final CreditJson creditJson = new CreditJson(invoice, credit);
         return Response.status(Response.Status.OK).entity(creditJson).build();
@@ -117,13 +117,13 @@ public class CreditResource extends JaxRsResourceBase {
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final Account account = accountUserApi.getAccountById(UUID.fromString(json.getAccountId()), callContext);
+        final Account account = accountUserApi.getAccountById(json.getAccountId(), callContext);
         final LocalDate effectiveDate = new LocalDate(clock.getUTCNow(), account.getTimeZone());
 
         final InvoiceItem credit;
         if (json.getInvoiceId() != null) {
             // Apply an invoice level credit
-            credit = invoiceUserApi.insertCreditForInvoice(account.getId(), UUID.fromString(json.getInvoiceId()), json.getCreditAmount(),
+            credit = invoiceUserApi.insertCreditForInvoice(account.getId(), json.getInvoiceId(), json.getCreditAmount(),
                                                            effectiveDate, account.getCurrency(), json.getDescription(), callContext);
         } else {
             // Apply a account level credit
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
index 6088379..69fcd94 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
@@ -57,7 +57,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.CUSTOM_FIELDS_PATH)
-@Api(value = JaxrsResource.CUSTOM_FIELDS_PATH, description = "Operations on custom fields")
+@Api(value = JaxrsResource.CUSTOM_FIELDS_PATH, description = "Operations on custom fields", tags="CustomField")
 public class CustomFieldResource extends JaxRsResourceBase {
 
     @Inject
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
index ea4be80..aeccced 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
@@ -52,7 +52,7 @@ import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
 
 @Singleton
 @Path(JaxrsResource.EXPORT_PATH)
-@Api(value = JaxrsResource.EXPORT_PATH, description = "Export endpoints")
+@Api(value = JaxrsResource.EXPORT_PATH, description = "Export endpoints", tags="Export")
 public class ExportResource extends JaxRsResourceBase {
 
     private final ExportUserApi exportUserApi;
@@ -78,13 +78,11 @@ public class ExportResource extends JaxRsResourceBase {
     @ApiOperation(value = "Export account data", response = String.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public StreamingOutput exportDataForAccount(@PathParam("accountId") final String accountIdStr
-            ,
+    public StreamingOutput exportDataForAccount(@PathParam("accountId") final UUID accountId,
                                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                 @HeaderParam(HDR_REASON) final String reason,
                                                 @HeaderParam(HDR_COMMENT) final String comment,
                                                 @javax.ws.rs.core.Context final HttpServletRequest request) {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
         return new StreamingOutput() {
             @Override
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
index 7235277..3b94ad5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceItemResource.java
@@ -58,13 +58,14 @@ import org.killbill.commons.metrics.TimedResource;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.INVOICES_ITEMS_PATH)
-@Api(value = JaxrsResource.INVOICES_ITEMS_PATH, description = "Operations on invoice items")
+@Api(value = JaxrsResource.INVOICES_ITEMS_PATH, description = "Operations on invoice items", tags="InvoiceItem")
 public class InvoiceItemResource extends JaxRsResourceBase {
     private static final String ID_PARAM_NAME = "invoiceItemId";
 
@@ -81,10 +82,10 @@ public class InvoiceItemResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve invoice item custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice item id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(id), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(id, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @TimedResource
@@ -94,14 +95,14 @@ public class InvoiceItemResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to invoice item")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice item id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(id), customFields,
+        return super.createCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -113,13 +114,13 @@ public class InvoiceItemResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to invoice item")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice item id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(id), customFields,
+        return super.modifyCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -131,13 +132,13 @@ public class InvoiceItemResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from invoice item")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice item id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(id), customFieldList,
+        return super.deleteCustomFields(id, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -148,16 +149,15 @@ public class InvoiceItemResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve invoice item tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice item id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
-                            @QueryParam(QUERY_ACCOUNT_ID) final String accountIdStr,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID id,
+                            @ApiParam(required=true) @QueryParam(QUERY_ACCOUNT_ID) final UUID accountId,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_TAGS_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, AccountApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final TenantContext tenantContext = context.createTenantContextWithAccountId(accountId, request);
         final Account account = accountUserApi.getAccountById(accountId, tenantContext);
 
-        return super.getTags(account.getId(), UUID.fromString(id), auditMode, includedDeleted, tenantContext);
+        return super.getTags(account.getId(), id, auditMode, includedDeleted, tenantContext);
     }
 
     @TimedResource
@@ -167,14 +167,14 @@ public class InvoiceItemResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to invoice item")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice item id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.createTags(UUID.fromString(id), tagList, uriInfo,
+        return super.createTags(id, tagList, uriInfo,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request), request);
     }
 
@@ -185,13 +185,13 @@ public class InvoiceItemResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from invoice item")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice item id supplied")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.deleteTags(UUID.fromString(id), tagList,
+        return super.deleteTags(id, tagList,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
index a98cea9..c75b4e5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
@@ -88,7 +88,7 @@ import io.swagger.annotations.ApiResponses;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.INVOICE_PAYMENTS_PATH)
-@Api(value = JaxrsResource.INVOICE_PAYMENTS_PATH, description = "Operations on invoice payments")
+@Api(value = JaxrsResource.INVOICE_PAYMENTS_PATH, description = "Operations on invoice payments", tags="InvoicePayment")
 public class InvoicePaymentResource extends JaxRsResourceBase {
 
     private static final String ID_PARAM_NAME = "paymentId";
@@ -116,7 +116,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve a payment by id", response = InvoicePaymentJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"),
                            @ApiResponse(code = 404, message = "Payment not found")})
-    public Response getInvoicePayment(@PathParam("paymentId") final String paymentIdStr,
+    public Response getInvoicePayment(@PathParam("paymentId") final UUID paymentId,
                                       @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                       @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
                                       @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
@@ -124,12 +124,11 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
 
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID paymentIdId = UUID.fromString(paymentIdStr);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final Payment payment = paymentApi.getPayment(paymentIdId, withPluginInfo, withAttempts, pluginProperties, tenantContext);
+        final Payment payment = paymentApi.getPayment(paymentId, withPluginInfo, withAttempts, pluginProperties, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
 
-        final List<InvoicePayment> invoicePayments = invoicePaymentApi.getInvoicePayments(paymentIdId, tenantContext);
+        final List<InvoicePayment> invoicePayments = invoicePaymentApi.getInvoicePayments(paymentId, tenantContext);
         final InvoicePayment invoicePayment = Iterables.tryFind(invoicePayments, new Predicate<InvoicePayment>() {
             @Override
             public boolean apply(final InvoicePayment input) {
@@ -151,9 +150,9 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"),
                            @ApiResponse(code = 404, message = "Account or payment not found")})
     public Response createRefundWithAdjustments(final InvoicePaymentTransactionJson json,
-                                                @PathParam("paymentId") final String paymentId,
+                                                @PathParam("paymentId") final UUID paymentId,
                                                 @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
-                                                @QueryParam(QUERY_PAYMENT_METHOD_ID) @DefaultValue("") final String paymentMethodId,
+                                                @QueryParam(QUERY_PAYMENT_METHOD_ID) final UUID paymentMethodId,
                                                 @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                 @HeaderParam(HDR_REASON) final String reason,
@@ -163,8 +162,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
         verifyNonNullOrEmpty(json, "InvoicePaymentTransactionJson body should be specified");
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID paymentUuid = UUID.fromString(paymentId);
-        final Payment payment = paymentApi.getPayment(paymentUuid, false, false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
 
         final Iterable<PluginProperty> pluginProperties;
@@ -174,7 +172,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
             if (json.getAdjustments() != null && json.getAdjustments().size() > 0) {
                 final Map<UUID, BigDecimal> adjustments = new HashMap<UUID, BigDecimal>();
                 for (final InvoiceItemJson item : json.getAdjustments()) {
-                    adjustments.put(UUID.fromString(item.getInvoiceItemId()), item.getAmount());
+                    adjustments.put(item.getInvoiceItemId(), item.getAmount());
                 }
                 pluginProperties = extractPluginProperties(pluginPropertiesString,
                                                            new PluginProperty("IPCD_REFUND_WITH_ADJUSTMENTS", "true", false),
@@ -189,11 +187,11 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
 
         final Payment result;
         if (externalPayment) {
-            UUID externalPaymentMethodId = Strings.isNullOrEmpty(paymentMethodId) ? null : UUID.fromString(paymentMethodId);
+            UUID externalPaymentMethodId = paymentMethodId;
 
             final Collection<PluginProperty> pluginPropertiesForExternalRefund = new LinkedList<PluginProperty>();
             Iterables.addAll(pluginPropertiesForExternalRefund, pluginProperties);
-            pluginPropertiesForExternalRefund.add(new PluginProperty("IPCD_PAYMENT_ID", paymentUuid, false));
+            pluginPropertiesForExternalRefund.add(new PluginProperty("IPCD_PAYMENT_ID", paymentId, false));
 
             result = paymentApi.createCreditWithPaymentControl(account, externalPaymentMethodId, null, json.getAmount(), account.getCurrency(), json.getEffectiveDate(),
                                                                paymentExternalKey, transactionExternalKey, pluginPropertiesForExternalRefund,
@@ -215,7 +213,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"),
                            @ApiResponse(code = 404, message = "Account or payment not found")})
     public Response createChargeback(final InvoicePaymentTransactionJson json,
-                                     @PathParam("paymentId") final String paymentId,
+                                     @PathParam("paymentId") final UUID paymentId,
                                      @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                      @HeaderParam(HDR_REASON) final String reason,
                                      @HeaderParam(HDR_COMMENT) final String comment,
@@ -225,8 +223,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
         verifyNonNullOrEmpty(json.getAmount(), "InvoicePaymentTransactionJson amount needs to be set");
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID paymentUuid = UUID.fromString(paymentId);
-        final Payment payment = paymentApi.getPayment(paymentUuid, false, false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
         final String transactionExternalKey = json.getTransactionExternalKey() != null ? json.getTransactionExternalKey() : UUIDs.randomUUID().toString();
 
@@ -244,18 +241,17 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"),
                            @ApiResponse(code = 404, message = "Account or payment not found")})
     public Response createChargebackReversal(final InvoicePaymentTransactionJson json,
-                                             @PathParam("paymentId") final String paymentId,
+                                             @PathParam("paymentId") final UUID paymentId,
                                              @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                              @HeaderParam(HDR_REASON) final String reason,
                                              @HeaderParam(HDR_COMMENT) final String comment,
                                              @javax.ws.rs.core.Context final UriInfo uriInfo,
                                              @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
         verifyNonNullOrEmpty(json, "InvoicePaymentTransactionJson body should be specified");
-        verifyNonNullOrEmpty(json.getTransactionExternalKey(), "transactionExternalKey amount needs to be set");
+        verifyNonNullOrEmpty(json.getTransactionExternalKey(), "InvoicePaymentTransactionJson transactionExternalKey needs to be set");
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID paymentUuid = UUID.fromString(paymentId);
-        final Payment payment = paymentApi.getPayment(paymentUuid, false, false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
 
         final Payment result = paymentApi.createChargebackReversalWithPaymentControl(account, payment.getId(), json.getEffectiveDate(), json.getTransactionExternalKey(), createInvoicePaymentControlPluginApiPaymentOptions(false), callContext);
@@ -278,7 +274,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response completeInvoicePaymentTransaction(final PaymentTransactionJson json,
-                                        @PathParam("paymentId") final String paymentIdStr,
+                                        @PathParam("paymentId") final UUID paymentId,
                                         @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                         @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -288,9 +284,6 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
 
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-
-        final UUID paymentId = UUID.fromString(paymentIdStr);
-
         final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), tenantContext);
         final List<InvoicePayment> invoicePayments = invoicePaymentApi.getInvoicePayments(paymentId, tenantContext);
 
@@ -324,10 +317,10 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve payment custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(id), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(id, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @TimedResource
@@ -337,14 +330,14 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(id), customFields,
+        return super.createCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -356,13 +349,13 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(id), customFields,
+        return super.modifyCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -374,13 +367,13 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(id), customFieldList,
+        return super.deleteCustomFields(id, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -391,13 +384,12 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve payment tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"),
                            @ApiResponse(code = 404, message = "Payment not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String paymentIdString,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID paymentId,
                             @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, PaymentApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID paymentId = UUID.fromString(paymentIdString);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Payment payment = paymentApi.getPayment(paymentId, false, false, pluginProperties, tenantContext);
         return super.getTags(payment.getAccountId(), paymentId, auditMode, includedDeleted, tenantContext);
@@ -410,14 +402,14 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.createTags(UUID.fromString(id), tagList, uriInfo,
+        return super.createTags(id, tagList, uriInfo,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request), request);
     }
 
@@ -428,13 +420,13 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.deleteTags(UUID.fromString(id), tagList,
+        return super.deleteTags(id, tagList,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index df9215f..8855d34 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -119,6 +119,7 @@ import com.google.common.collect.Ordering;
 import com.google.inject.Inject;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
@@ -127,7 +128,7 @@ import static javax.ws.rs.core.MediaType.TEXT_HTML;
 import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
 
 @Path(JaxrsResource.INVOICES_PATH)
-@Api(value = JaxrsResource.INVOICES_PATH, description = "Operations on invoices")
+@Api(value = JaxrsResource.INVOICES_PATH, description = "Operations on invoices", tags="Invoice")
 public class InvoiceResource extends JaxRsResourceBase {
 
     private static final Logger log = LoggerFactory.getLogger(InvoiceResource.class);
@@ -169,13 +170,13 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve an invoice by id", response = InvoiceJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied"),
                            @ApiResponse(code = 404, message = "Invoice not found")})
-    public Response getInvoice(@PathParam("invoiceId") final String invoiceId,
+    public Response getInvoice(@PathParam("invoiceId") final UUID invoiceId,
                                @QueryParam(QUERY_INVOICE_WITH_ITEMS) @DefaultValue("false") final boolean withItems,
                                @QueryParam(QUERY_INVOICE_WITH_CHILDREN_ITEMS) @DefaultValue("false") final boolean withChildrenItems,
                                @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId), tenantContext);
+        final Invoice invoice = invoiceApi.getInvoice(invoiceId, tenantContext);
         final List<InvoiceItem> childInvoiceItems = withChildrenItems ? invoiceApi.getInvoiceItemsByParentInvoice(invoice.getId(), tenantContext) : null;
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(invoice.getAccountId(), auditMode.getLevel(), tenantContext);
 
@@ -217,9 +218,9 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(TEXT_HTML)
     @ApiOperation(value = "Render an invoice as HTML", response = String.class)
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Invoice not found")})
-    public Response getInvoiceAsHTML(@PathParam("invoiceId") final String invoiceId,
+    public Response getInvoiceAsHTML(@PathParam("invoiceId") final UUID invoiceId,
                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException, IOException, AccountApiException {
-        return Response.status(Status.OK).entity(invoiceApi.getInvoiceAsHTML(UUID.fromString(invoiceId), context.createTenantContextNoAccountId(request))).build();
+        return Response.status(Status.OK).entity(invoiceApi.getInvoiceAsHTML(invoiceId, context.createTenantContextNoAccountId(request))).build();
     }
 
     @TimedResource
@@ -293,7 +294,7 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Trigger an invoice generation", response = InvoiceJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id or target datetime supplied")})
-    public Response createFutureInvoice(@QueryParam(QUERY_ACCOUNT_ID) final String accountIdStr,
+    public Response createFutureInvoice(@ApiParam(required=true) @QueryParam(QUERY_ACCOUNT_ID) final UUID accountId,
                                         @QueryParam(QUERY_TARGET_DATE) final String targetDate,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
@@ -301,7 +302,6 @@ public class InvoiceResource extends JaxRsResourceBase {
                                         @javax.ws.rs.core.Context final HttpServletRequest request,
                                         @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
 
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
         final LocalDate inputDate = toLocalDate(targetDate);
 
@@ -322,17 +322,16 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Path("/" + MIGRATION + "/{accountId:" + UUID_PATTERN + "}")
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
-    @ApiOperation(value = "Create a migration invoice", response = InvoiceJson.class)
+    @ApiOperation(value = "Create a migration invoice", response = InvoiceJson.class, tags="Invoice")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id or target datetime supplied")})
-    public Response createMigrationInvoice(final Iterable<InvoiceItemJson> items,
-                                           @PathParam("accountId") final String accountIdStr,
+    public Response createMigrationInvoice(final List<InvoiceItemJson> items,
+                                           @PathParam("accountId") final UUID accountId,
                                            @Nullable @QueryParam(QUERY_TARGET_DATE) final String targetDate,
                                            @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                            @HeaderParam(HDR_REASON) final String reason,
                                            @HeaderParam(HDR_COMMENT) final String comment,
                                            @javax.ws.rs.core.Context final HttpServletRequest request,
                                            @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(accountId, callContext);
@@ -350,14 +349,13 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiOperation(value = "Generate a dryRun invoice", response = InvoiceJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id or target datetime supplied")})
     public Response generateDryRunInvoice(@Nullable final InvoiceDryRunJson dryRunSubscriptionSpec,
-                                          @QueryParam(QUERY_ACCOUNT_ID) final String accountIdStr,
+                                          @ApiParam(required=true) @QueryParam(QUERY_ACCOUNT_ID) final UUID accountId,
                                           @Nullable @QueryParam(QUERY_TARGET_DATE) final String targetDate,
                                           @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                           @HeaderParam(HDR_REASON) final String reason,
                                           @HeaderParam(HDR_COMMENT) final String comment,
                                           @javax.ws.rs.core.Context final HttpServletRequest request,
                                           @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
         final LocalDate inputDate;
         if (dryRunSubscriptionSpec != null) {
@@ -414,19 +412,18 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiOperation(value = "Delete a CBA item")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id, invoice id or invoice item id supplied"),
                            @ApiResponse(code = 404, message = "Account or invoice not found")})
-    public Response deleteCBA(@PathParam("invoiceId") final String invoiceId,
-                              @PathParam("invoiceItemId") final String invoiceItemId,
-                              @QueryParam(QUERY_ACCOUNT_ID) final String accountIdStr,
+    public Response deleteCBA(@PathParam("invoiceId") final UUID invoiceId,
+                              @PathParam("invoiceItemId") final UUID invoiceItemId,
+                              @ApiParam(required=true) @QueryParam(QUERY_ACCOUNT_ID) final UUID accountId,
                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
                               @HeaderParam(HDR_REASON) final String reason,
                               @HeaderParam(HDR_COMMENT) final String comment,
                               @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(accountId, callContext);
 
-        invoiceApi.deleteCBA(account.getId(), UUID.fromString(invoiceId), UUID.fromString(invoiceItemId), callContext);
+        invoiceApi.deleteCBA(account.getId(), invoiceId, invoiceItemId, callContext);
 
         return Response.status(Status.OK).build();
     }
@@ -440,7 +437,7 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id, invoice id or invoice item id supplied"),
                            @ApiResponse(code = 404, message = "Invoice not found")})
     public Response adjustInvoiceItem(final InvoiceItemJson json,
-                                      @PathParam("invoiceId") final String invoiceId,
+                                      @PathParam("invoiceId") final UUID invoiceId,
                                       @QueryParam(QUERY_REQUESTED_DT) final String requestedDateTimeString,
                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                       @HeaderParam(HDR_REASON) final String reason,
@@ -451,22 +448,22 @@ public class InvoiceResource extends JaxRsResourceBase {
         verifyNonNullOrEmpty(json.getAccountId(), "InvoiceItemJson accountId needs to be set",
                              json.getInvoiceItemId(), "InvoiceItemJson invoiceItemId needs to be set");
 
-        final UUID accountId = UUID.fromString(json.getAccountId());
+        final UUID accountId = json.getAccountId();
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final LocalDate requestedDate = toLocalDateDefaultToday(accountId, requestedDateTimeString, callContext);
         final InvoiceItem adjustmentItem;
         if (json.getAmount() == null) {
             adjustmentItem = invoiceApi.insertInvoiceItemAdjustment(accountId,
-                                                                    UUID.fromString(invoiceId),
-                                                                    UUID.fromString(json.getInvoiceItemId()),
+                                                                    invoiceId,
+                                                                    json.getInvoiceItemId(),
                                                                     requestedDate,
                                                                     json.getDescription(),
                                                                     callContext);
         } else {
             adjustmentItem = invoiceApi.insertInvoiceItemAdjustment(accountId,
-                                                                    UUID.fromString(invoiceId),
-                                                                    UUID.fromString(json.getInvoiceItemId()),
+                                                                    invoiceId,
+                                                                    json.getInvoiceItemId(),
                                                                     requestedDate,
                                                                     json.getAmount(),
                                                                     Currency.valueOf(json.getCurrency()),
@@ -489,8 +486,8 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiOperation(value = "Create external charge(s)", response = InvoiceItemJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
-    public Response createExternalCharges(final Iterable<InvoiceItemJson> externalChargesJson,
-                                          @PathParam("accountId") final String accountIdStr,
+    public Response createExternalCharges(final List<InvoiceItemJson> externalChargesJson,
+                                          @PathParam("accountId") final UUID accountId,
                                           @QueryParam(QUERY_REQUESTED_DT) final String requestedDateTimeString,
                                           @QueryParam(QUERY_PAY_INVOICE) @DefaultValue("false") final Boolean payInvoice,
                                           @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
@@ -504,7 +501,6 @@ public class InvoiceResource extends JaxRsResourceBase {
                                           @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException, PaymentApiException {
 
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID accountId = UUID.fromString(accountIdStr);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(accountId, callContext);
@@ -604,14 +600,14 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve payments associated with an invoice", response = InvoicePaymentJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied"),
                            @ApiResponse(code = 404, message = "Invoice not found")})
-    public Response getPayments(@PathParam("invoiceId") final String invoiceId,
+    public Response getPayments(@PathParam("invoiceId") final UUID invoiceId,
                                 @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                 @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                 @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, InvoiceApiException {
 
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId), tenantContext);
+        final Invoice invoice = invoiceApi.getInvoice(invoiceId, tenantContext);
 
         // Extract unique set of paymentId for this invoice
         final Set<UUID> invoicePaymentIds = ImmutableSet.copyOf(Iterables.transform(invoice.getPayments(), new Function<InvoicePayment, UUID>() {
@@ -648,7 +644,7 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid account id or invoice id supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
     public Response createInstantPayment(final InvoicePaymentJson payment,
-                                         @PathParam("invoiceId") final String invoiceId,
+                                         @PathParam("invoiceId") final UUID invoiceId,
                                          @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
                                          @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                          @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -665,11 +661,11 @@ public class InvoiceResource extends JaxRsResourceBase {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final Account account = accountUserApi.getAccountById(UUID.fromString(payment.getAccountId()), callContext);
+        final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
         final UUID paymentMethodId = externalPayment ? null :
-                                     (payment.getPaymentMethodId() != null ? UUID.fromString(payment.getPaymentMethodId()) : account.getPaymentMethodId());
+                                     (payment.getPaymentMethodId() != null ? payment.getPaymentMethodId() : account.getPaymentMethodId());
 
-        final Payment result = createPurchaseForInvoice(account, UUID.fromString(invoiceId), payment.getPurchasedAmount(), paymentMethodId, externalPayment,
+        final Payment result = createPurchaseForInvoice(account, invoiceId, payment.getPurchasedAmount(), paymentMethodId, externalPayment,
                                                         payment.getPaymentExternalKey(), null, pluginProperties, callContext);
         return result != null ?
                uriBuilder.buildResponse(uriInfo, InvoicePaymentResource.class, "getInvoicePayment", result.getId(), request) :
@@ -879,10 +875,10 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve invoice custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(id), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(id, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @TimedResource
@@ -892,14 +888,14 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to invoice")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(id), customFields,
+        return super.createCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -911,13 +907,13 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to invoice")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(id), customFields,
+        return super.modifyCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -928,13 +924,13 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from invoice")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(id), customFieldList,
+        return super.deleteCustomFields(id, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -945,11 +941,10 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve invoice tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied"),
                            @ApiResponse(code = 404, message = "Invoice not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String invoiceIdString,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID invoiceId,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, InvoiceApiException {
-        final UUID invoiceId = UUID.fromString(invoiceIdString);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Invoice invoice = invoiceApi.getInvoice(invoiceId, tenantContext);
         return super.getTags(invoice.getAccountId(), invoiceId, auditMode, includedDeleted, tenantContext);
@@ -962,14 +957,14 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to invoice")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.createTags(UUID.fromString(id), tagList, uriInfo,
+        return super.createTags(id, tagList, uriInfo,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request), request);
     }
 
@@ -980,13 +975,13 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from invoice")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.deleteTags(UUID.fromString(id), tagList,
+        return super.deleteTags(id, tagList,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -997,7 +992,7 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Perform the invoice status transition from DRAFT to COMMITTED")
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Invoice not found")})
-    public Response commitInvoice(@PathParam("invoiceId") final String invoiceIdString,
+    public Response commitInvoice(@PathParam("invoiceId") final UUID invoiceId,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
                                   @HeaderParam(HDR_COMMENT) final String comment,
@@ -1005,7 +1000,6 @@ public class InvoiceResource extends JaxRsResourceBase {
                                   @javax.ws.rs.core.Context final UriInfo uriInfo) throws InvoiceApiException {
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID invoiceId = UUID.fromString(invoiceIdString);
         invoiceApi.commitInvoice(invoiceId, callContext);
         return Response.status(Response.Status.OK).build();
     }
@@ -1018,7 +1012,7 @@ public class InvoiceResource extends JaxRsResourceBase {
     @ApiOperation(value = "Perform the action of voiding an invoice")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid invoice id supplied"),
                            @ApiResponse(code = 404, message = "Invoice not found")})
-    public Response voidInvoice(@PathParam("invoiceId") final String invoiceIdString,
+    public Response voidInvoice(@PathParam("invoiceId") final UUID invoiceId,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
                                   @HeaderParam(HDR_COMMENT) final String comment,
@@ -1026,7 +1020,6 @@ public class InvoiceResource extends JaxRsResourceBase {
                                   @javax.ws.rs.core.Context final UriInfo uriInfo) throws InvoiceApiException {
 
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID invoiceId = UUID.fromString(invoiceIdString);
         invoiceApi.voidInvoice(invoiceId, callContext);
         return Response.status(Response.Status.OK).build();
     }
@@ -1060,8 +1053,8 @@ public class InvoiceResource extends JaxRsResourceBase {
             } else {
                 this.dryRunType = input.getDryRunType() != null ? DryRunType.valueOf(input.getDryRunType()) : DryRunType.TARGET_DATE;
                 this.action = input.getDryRunAction() != null ? SubscriptionEventType.valueOf(input.getDryRunAction()) : null;
-                this.subscriptionId = input.getSubscriptionId() != null ? UUID.fromString(input.getSubscriptionId()) : null;
-                this.bundleId = input.getBundleId() != null ? UUID.fromString(input.getBundleId()) : null;
+                this.subscriptionId = input.getSubscriptionId();
+                this.bundleId = input.getBundleId();
                 this.effectiveDate = input.getEffectiveDate();
                 this.billingPolicy = input.getBillingPolicy() != null ? BillingActionPolicy.valueOf(input.getBillingPolicy()) : null;
                 final PlanPhaseSpecifier planPhaseSpecifier = (input.getProductName() != null &&
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
index f0490db..a6ed103 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -162,7 +162,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
     }
 
     public Response addBlockingState(final BlockingStateJson json,
-                                     final String id,
+                                     final UUID blockableId,
                                      final BlockingStateType type,
                                      final String requestedDate,
                                      final List<String> pluginPropertiesString,
@@ -173,7 +173,6 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
 
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final UUID blockableId = UUID.fromString(id);
 
         final boolean isBlockBilling = (json.isBlockBilling() != null && json.isBlockBilling());
         final boolean isBlockEntitlement = (json.isBlockEntitlement() != null && json.isBlockEntitlement());
@@ -277,7 +276,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         for (final CustomFieldJson cur : customFields) {
             verifyNonNullOrEmpty(cur.getCustomFieldId(), "CustomFieldJson id needs to be set");
             verifyNonNullOrEmpty(cur.getValue(), "CustomFieldJson value needs to be set");
-            input.add(new StringCustomField(UUID.fromString(cur.getCustomFieldId()), cur.getName(), cur.getValue(), getObjectType(), id, context.getCreatedDate()));
+            input.add(new StringCustomField(cur.getCustomFieldId(), cur.getName(), cur.getValue(), getObjectType(), id, context.getCreatedDate()));
         }
 
         customFieldUserApi.updateCustomFields(input, context);
@@ -374,10 +373,9 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         }
     }
 
-    protected Payment getPaymentByIdOrKey(@Nullable final String paymentIdStr, @Nullable final String externalKey, final Iterable<PluginProperty> pluginProperties, final TenantContext tenantContext) throws PaymentApiException {
-        Preconditions.checkArgument(paymentIdStr != null || externalKey != null, "Need to set either paymentId or payment externalKey");
-        if (paymentIdStr != null) {
-            final UUID paymentId = UUID.fromString(paymentIdStr);
+    protected Payment getPaymentByIdOrKey(@Nullable final UUID paymentId, @Nullable final String externalKey, final Iterable<PluginProperty> pluginProperties, final TenantContext tenantContext) throws PaymentApiException {
+        Preconditions.checkArgument(paymentId != null || externalKey != null, "Need to set either paymentId or payment externalKey");
+        if (paymentId != null) {
             return paymentApi.getPayment(paymentId, false, false, pluginProperties, tenantContext);
         } else {
             return paymentApi.getPaymentByExternalKey(externalKey, false, false, pluginProperties, tenantContext);
@@ -446,14 +444,14 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
     }
 
 
-    protected PaymentTransaction lookupPendingOrSuccessTransaction(final Payment initialPayment, @Nullable final String transactionId, @Nullable final String transactionExternalKey, @Nullable final String transactionType) throws PaymentApiException {
+    protected PaymentTransaction lookupPendingOrSuccessTransaction(final Payment initialPayment, @Nullable final UUID transactionId, @Nullable final String transactionExternalKey, @Nullable final String transactionType) throws PaymentApiException {
         final Collection<PaymentTransaction> pendingTransaction = Collections2.filter(initialPayment.getTransactions(), new Predicate<PaymentTransaction>() {
             @Override
             public boolean apply(final PaymentTransaction input) {
                 if (input.getTransactionStatus() != TransactionStatus.PENDING && input.getTransactionStatus() != TransactionStatus.SUCCESS) {
                     return false;
                 }
-                if (transactionId != null && !transactionId.equals(input.getId().toString())) {
+                if (transactionId != null && !transactionId.equals(input.getId())) {
                     return false;
                 }
                 if (transactionExternalKey != null && !transactionExternalKey.equals(input.getExternalKey())) {
@@ -476,7 +474,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
                 final String parameterValue;
                 if (transactionId != null) {
                     parameterType = "transactionId";
-                    parameterValue = transactionId;
+                    parameterValue = transactionId.toString();
                 } else if (transactionExternalKey != null) {
                     parameterType = "transactionExternalKey";
                     parameterValue = transactionExternalKey;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/KillBillApiDefinition.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/KillBillApiDefinition.java
new file mode 100644
index 0000000..c845a5f
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/KillBillApiDefinition.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.jaxrs.resources;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLog;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import io.swagger.annotations.SwaggerDefinition;
+import io.swagger.jaxrs.config.ReaderListener;
+import io.swagger.models.Model;
+import io.swagger.models.Operation;
+import io.swagger.models.Path;
+import io.swagger.models.Swagger;
+import io.swagger.models.auth.BasicAuthDefinition;
+import io.swagger.models.parameters.BodyParameter;
+import io.swagger.models.parameters.HeaderParameter;
+import io.swagger.models.parameters.Parameter;
+import io.swagger.models.parameters.PathParameter;
+import io.swagger.models.parameters.QueryParameter;
+import io.swagger.models.properties.Property;
+
+import static org.killbill.billing.jaxrs.resources.JaxrsResource.HDR_CREATED_BY;
+import static org.killbill.billing.jaxrs.resources.JaxrsResource.QUERY_AUDIT;
+
+@SwaggerDefinition
+public class KillBillApiDefinition implements ReaderListener {
+
+    public static final String BASIC_AUTH_SCHEME = "basicAuth";
+
+    @Override
+    public void beforeScan(final io.swagger.jaxrs.Reader reader, final Swagger swagger) {
+        BasicAuthDefinition basicAuthDefinition = new BasicAuthDefinition();
+        swagger.addSecurityDefinition(BASIC_AUTH_SCHEME, basicAuthDefinition);
+    }
+
+    @Override
+    public void afterScan(final io.swagger.jaxrs.Reader reader, final Swagger swagger) {
+
+        final HeaderParameter apiKeyParam = new HeaderParameter();
+        apiKeyParam.setName("X-Killbill-ApiKey");
+        apiKeyParam.setType("string");
+        apiKeyParam.setRequired(true);
+
+        final HeaderParameter apiSecretParam = new HeaderParameter();
+        apiSecretParam.setName("X-Killbill-ApiSecret");
+        apiSecretParam.setType("string");
+        apiSecretParam.setRequired(true);
+
+        for (final String pathName : swagger.getPaths().keySet()) {
+            final Path path = swagger.getPaths().get(pathName);
+            decorateOperation(path.getGet(), pathName, "GET", apiKeyParam, apiSecretParam);
+            decorateOperation(path.getPost(), pathName, "POST", apiKeyParam, apiSecretParam);
+            decorateOperation(path.getPut(), pathName, "PUT", apiKeyParam, apiSecretParam);
+            decorateOperation(path.getDelete(), pathName, "DELETE", apiKeyParam, apiSecretParam);
+            decorateOperation(path.getOptions(), pathName, "OPTIONS", apiKeyParam, apiSecretParam);
+
+        }
+
+        for (final Model m : swagger.getDefinitions().values()) {
+            if (m.getProperties() != null) {
+                for (final Property p : m.getProperties().values()) {
+                    p.setReadOnly(false);
+                }
+            }
+        }
+    }
+
+    private void decorateOperation(final Operation op, final String pathName, final String httpMethod, final HeaderParameter apiKeyParam, final HeaderParameter apiSecretParam) {
+        if (op != null) {
+            op.addSecurity(BASIC_AUTH_SCHEME, null);
+            if (requiresTenantInformation(pathName, httpMethod)) {
+                op.addParameter(apiKeyParam);
+                op.addParameter(apiSecretParam);
+            }
+
+            for (Parameter p : op.getParameters()) {
+                if (p instanceof BodyParameter) {
+                    p.setRequired(true);
+                } else if (p instanceof PathParameter) {
+                    p.setRequired(true);
+                } else if (p instanceof HeaderParameter) {
+                    if (p.getName().equals(HDR_CREATED_BY)) {
+                        p.setRequired(true);
+                    }
+                } else if (p instanceof QueryParameter) {
+                    QueryParameter qp = (QueryParameter) p;
+                    if (qp.getName().equals(QUERY_AUDIT)) {
+                        qp.setName("auditLevel");
+                        qp.setRequired(false);
+                        qp.setType("string");
+                        final List<String> values = ImmutableList.copyOf(Iterables.transform(ImmutableList.<AuditLevel>copyOf(AuditLevel.values()), new Function<AuditLevel, String>() {
+                            @Override
+                            public String apply(final AuditLevel input) {
+                                return input.toString();
+                            }
+                        }));
+                        qp.setEnum(values);
+                    }
+                }
+            }
+        }
+    }
+
+    public static boolean requiresTenantInformation(final String path, final String httpMethod) {
+        boolean shouldSkipTenantInfoForRequests = (
+                // Chicken - egg problem
+                isTenantCreationRequest(path, httpMethod) ||
+                // Retrieve user permissions should not require tenant info since this is cross tenants
+                isPermissionRequest(path) ||
+                // Node request are cross tenant
+                isNodeInfoRequest(path) ||
+                // See KillBillShiroWebModule#CorsBasicHttpAuthenticationFilter
+                isOptionsRequest(httpMethod) ||
+                // Shift the responsibility to the plugin
+                isPluginRequest(path) ||
+                // Static resources (welcome screen, Swagger, etc.)
+                isNotKbNorPluginResourceRequest(path, httpMethod));
+        return !shouldSkipTenantInfoForRequests;
+    }
+
+    private static boolean isPermissionRequest(final String path) {
+        return path != null && path.startsWith(JaxrsResource.SECURITY_PATH);
+    }
+
+    private static boolean isTenantCreationRequest(final String path, final String httpMethod) {
+        return JaxrsResource.TENANTS_PATH.equals(path) && "POST".equalsIgnoreCase(httpMethod);
+    }
+
+    private static boolean isNodeInfoRequest(final String path) {
+        return JaxrsResource.NODES_INFO_PATH.equals(path);
+    }
+
+    private static boolean isOptionsRequest(final String httpMethod) {
+        return "OPTIONS".equalsIgnoreCase(httpMethod);
+    }
+
+    private static boolean isNotKbNorPluginResourceRequest(final String path, final String httpMethod) {
+        return !isPluginRequest(path) && !isKbApiRequest(path) && "GET".equalsIgnoreCase(httpMethod);
+    }
+
+    private static boolean isKbApiRequest(final String path) {
+        return path != null && path.startsWith(JaxrsResource.PREFIX);
+    }
+
+    private static boolean isPluginRequest(final String path) {
+        return path != null && path.startsWith(JaxrsResource.PLUGINS_PATH);
+    }
+
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java
index e1d38f7..69e0d40 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/NodesInfoResource.java
@@ -72,7 +72,7 @@ import io.swagger.annotations.ApiResponses;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.NODES_INFO_PATH)
-@Api(value = JaxrsResource.NODES_INFO_PATH, description = "Operations to retrieve nodes info")
+@Api(value = JaxrsResource.NODES_INFO_PATH, description = "Operations to retrieve nodes info", tags="NodesInfo")
 public class NodesInfoResource extends JaxRsResourceBase {
 
     private final KillbillNodesApi killbillInfoApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java
index 82b4c72..6281a83 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/OverdueResource.java
@@ -61,7 +61,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_XML;
 
 @Singleton
 @Path(JaxrsResource.OVERDUE_PATH)
-@Api(value = JaxrsResource.OVERDUE_PATH, description = "Overdue information")
+@Api(value = JaxrsResource.OVERDUE_PATH, description = "Overdue information", tags="Overdue")
 public class OverdueResource extends JaxRsResourceBase {
 
     private final OverdueApi overdueApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
index 671c99d..818b4ff 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
@@ -67,7 +67,7 @@ import static javax.ws.rs.core.MediaType.WILDCARD;
 
 @Singleton
 @Path(JaxrsResource.PAYMENT_GATEWAYS_PATH)
-@Api(value = JaxrsResource.PAYMENT_GATEWAYS_PATH, description = "HPP endpoints")
+@Api(value = JaxrsResource.PAYMENT_GATEWAYS_PATH, description = "HPP endpoints", tags="PaymentGateway")
 public class PaymentGatewayResource extends ComboPaymentResource {
 
     private final PaymentGatewayApi paymentGatewayApi;
@@ -130,8 +130,8 @@ public class PaymentGatewayResource extends ComboPaymentResource {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid accountId supplied"),
                            @ApiResponse(code = 404, message = "Account not found")})
     public Response buildFormDescriptor(final HostedPaymentPageFieldsJson json,
-                                        @PathParam("accountId") final String accountIdString,
-                                        @QueryParam(QUERY_PAYMENT_METHOD_ID) final String paymentMethodIdStr,
+                                        @PathParam("accountId") final UUID accountId,
+                                        @QueryParam(QUERY_PAYMENT_METHOD_ID) final UUID inputPaymentMethodId,
                                         @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                         @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -141,10 +141,9 @@ public class PaymentGatewayResource extends ComboPaymentResource {
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final PaymentOptions paymentOptions = createControlPluginApiPaymentOptions(paymentControlPluginNames);
-        final UUID accountId = UUID.fromString(accountIdString);
         final CallContext callContext = context.createCallContextWithAccountId(accountId, createdBy, reason, comment, request);
         final Account account = accountUserApi.getAccountById(accountId, callContext);
-        final UUID paymentMethodId = paymentMethodIdStr == null ? account.getPaymentMethodId() : UUID.fromString(paymentMethodIdStr);
+        final UUID paymentMethodId = inputPaymentMethodId == null ? account.getPaymentMethodId() : inputPaymentMethodId;
 
         validatePaymentMethodForAccount(accountId, paymentMethodId, callContext);
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
index e765694..89e3ac5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
@@ -71,6 +71,7 @@ import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
@@ -78,7 +79,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.PAYMENT_METHODS_PATH)
-@Api(value = JaxrsResource.PAYMENT_METHODS_PATH, description = "Operations on payment methods")
+@Api(value = JaxrsResource.PAYMENT_METHODS_PATH, description = "Operations on payment methods", tags="PaymentMethod")
 public class PaymentMethodResource extends JaxRsResourceBase {
 
     @Inject
@@ -100,7 +101,7 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve a payment method by id", response = PaymentMethodJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentMethodId supplied"),
                            @ApiResponse(code = 404, message = "Account or payment method not found")})
-    public Response getPaymentMethod(@PathParam("paymentMethodId") final String paymentMethodId,
+    public Response getPaymentMethod(@PathParam("paymentMethodId") final UUID paymentMethodId,
                                      @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                      @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                                      @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@@ -109,7 +110,7 @@ public class PaymentMethodResource extends JaxRsResourceBase {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
 
-        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), includedDeleted, withPluginInfo, pluginProperties, tenantContext);
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(paymentMethodId, includedDeleted, withPluginInfo, pluginProperties, tenantContext);
         final Account account = accountUserApi.getAccountById(paymentMethod.getAccountId(), tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(paymentMethod.getAccountId(), auditMode.getLevel(), tenantContext);
         final PaymentMethodJson json = PaymentMethodJson.toPaymentMethodJson(account, paymentMethod, accountAuditLogs);
@@ -122,7 +123,7 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve a payment method by external key", response = PaymentMethodJson.class)
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Account or payment method not found")})
-    public Response getPaymentMethodByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
+    public Response getPaymentMethodByKey(@ApiParam(required=true) @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
                                           @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                           @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                                           @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@@ -260,7 +261,7 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @ApiOperation(value = "Delete a payment method")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentMethodId supplied"),
                            @ApiResponse(code = 404, message = "Account or payment method not found")})
-    public Response deletePaymentMethod(@PathParam("paymentMethodId") final String paymentMethodId,
+    public Response deletePaymentMethod(@PathParam("paymentMethodId") final UUID paymentMethodId,
                                         @QueryParam(QUERY_DELETE_DEFAULT_PM_WITH_AUTO_PAY_OFF) @DefaultValue("false") final Boolean deleteDefaultPaymentMethodWithAutoPayOff,
                                         @QueryParam(QUERY_FORCE_DEFAULT_PM_DELETION) @DefaultValue("false") final Boolean forceDefaultPaymentMethodDeletion,
                                         @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
@@ -271,10 +272,10 @@ public class PaymentMethodResource extends JaxRsResourceBase {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), false, false, pluginProperties, callContext);
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(paymentMethodId, false, false, pluginProperties, callContext);
         final Account account = accountUserApi.getAccountById(paymentMethod.getAccountId(), callContext);
 
-        paymentApi.deletePaymentMethod(account, UUID.fromString(paymentMethodId), deleteDefaultPaymentMethodWithAutoPayOff, forceDefaultPaymentMethodDeletion, pluginProperties, callContext);
+        paymentApi.deletePaymentMethod(account, paymentMethodId, deleteDefaultPaymentMethodWithAutoPayOff, forceDefaultPaymentMethodDeletion, pluginProperties, callContext);
 
         return Response.status(Status.OK).build();
     }
@@ -285,10 +286,10 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve payment method custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment method id supplied")})
-    public Response getCustomFields(@PathParam("paymentMethodId") final String paymentMethodId,
+    public Response getCustomFields(@PathParam("paymentMethodId") final UUID paymentMethodId,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(paymentMethodId), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(paymentMethodId, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @TimedResource
@@ -298,14 +299,14 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to payment method")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment method id supplied")})
-    public Response createCustomFields(@PathParam("paymentMethodId") final String paymentMethodId,
+    public Response createCustomFields(@PathParam("paymentMethodId") final UUID paymentMethodId,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(paymentMethodId), customFields,
+        return super.createCustomFields(paymentMethodId, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -317,13 +318,13 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to payment method")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment method id supplied")})
-    public Response modifyCustomFields(@PathParam("paymentMethodId") final String paymentMethodId,
+    public Response modifyCustomFields(@PathParam("paymentMethodId") final UUID paymentMethodId,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(paymentMethodId), customFields,
+        return super.modifyCustomFields(paymentMethodId, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -335,13 +336,13 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from payment method")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment method id supplied")})
-    public Response deleteCustomFields(@PathParam("paymentMethodId") final String paymentMethodId,
+    public Response deleteCustomFields(@PathParam("paymentMethodId") final UUID paymentMethodId,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(paymentMethodId), customFieldList,
+        return super.deleteCustomFields(paymentMethodId, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index 4e11dc8..6c7d14c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -81,13 +81,14 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.PAYMENTS_PATH)
-@Api(value = JaxrsResource.PAYMENTS_PATH, description = "Operations on payments")
+@Api(value = JaxrsResource.PAYMENTS_PATH, description = "Operations on payments", tags="Payment")
 public class PaymentResource extends ComboPaymentResource {
 
     private static final String ID_PARAM_NAME = "paymentId";
@@ -111,16 +112,15 @@ public class PaymentResource extends ComboPaymentResource {
     @ApiOperation(value = "Retrieve a payment by id", response = PaymentJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentId supplied"),
                            @ApiResponse(code = 404, message = "Payment not found")})
-    public Response getPayment(@PathParam("paymentId") final String paymentIdStr,
+    public Response getPayment(@PathParam("paymentId") final UUID paymentId,
                                @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
                                @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID paymentIdId = UUID.fromString(paymentIdStr);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final Payment payment = paymentApi.getPayment(paymentIdId, withPluginInfo, withAttempts, pluginProperties, tenantContext);
+        final Payment payment = paymentApi.getPayment(paymentId, withPluginInfo, withAttempts, pluginProperties, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
         final PaymentJson result = new PaymentJson(payment, accountAuditLogs);
         return Response.status(Response.Status.OK).entity(result).build();
@@ -133,7 +133,7 @@ public class PaymentResource extends ComboPaymentResource {
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Payment not found")})
     public Response getPaymentByExternalKey(@QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                             @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
-                                            @QueryParam(QUERY_EXTERNAL_KEY) final String paymentExternalKey,
+                                            @ApiParam(required=true) @QueryParam(QUERY_EXTERNAL_KEY) final String paymentExternalKey,
                                             @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                             @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
@@ -252,7 +252,7 @@ public class PaymentResource extends ComboPaymentResource {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response completeTransaction(@MetricTag(tag = "type", property = "transactionType") final PaymentTransactionJson json,
-                                        @PathParam("paymentId") final String paymentIdStr,
+                                        @PathParam("paymentId") final UUID paymentId,
                                         @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                         @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -260,7 +260,7 @@ public class PaymentResource extends ComboPaymentResource {
                                         @HeaderParam(HDR_COMMENT) final String comment,
                                         @javax.ws.rs.core.Context final UriInfo uriInfo,
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-        return completeTransactionInternalWithoutPayment(json, paymentIdStr, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+        return completeTransactionInternalWithoutPayment(json, paymentId, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
     }
 
 
@@ -309,7 +309,7 @@ public class PaymentResource extends ComboPaymentResource {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response captureAuthorization(final PaymentTransactionJson json,
-                                         @PathParam("paymentId") final String paymentIdStr,
+                                         @PathParam("paymentId") final UUID paymentId,
                                          @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                          @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                          @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -317,7 +317,7 @@ public class PaymentResource extends ComboPaymentResource {
                                          @HeaderParam(HDR_COMMENT) final String comment,
                                          @javax.ws.rs.core.Context final UriInfo uriInfo,
                                          @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-        return captureAuthorizationInternal(json, paymentIdStr, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+        return captureAuthorizationInternal(json, paymentId, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
     }
 
     @TimedResource(name = "captureAuthorization")
@@ -344,7 +344,7 @@ public class PaymentResource extends ComboPaymentResource {
     }
 
     private Response captureAuthorizationInternal(final PaymentTransactionJson json,
-                                                  @Nullable final String paymentIdStr,
+                                                  @Nullable final UUID paymentId,
                                                   final List<String> paymentControlPluginNames,
                                                   final List<String> pluginPropertiesString,
                                                   final String createdBy,
@@ -360,7 +360,7 @@ public class PaymentResource extends ComboPaymentResource {
         final Iterable<PluginProperty> pluginPropertiesFromQuery = extractPluginProperties(pluginPropertiesString);
         final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
+        final Payment initialPayment = getPaymentByIdOrKey(paymentId, json.getPaymentExternalKey(), pluginProperties, callContext);
 
         final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
         final Currency currency = json.getCurrency() == null ? account.getCurrency() : Currency.valueOf(json.getCurrency());
@@ -387,7 +387,7 @@ public class PaymentResource extends ComboPaymentResource {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response refundPayment(final PaymentTransactionJson json,
-                                  @PathParam("paymentId") final String paymentIdStr,
+                                  @PathParam("paymentId") final UUID paymentId,
                                   @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                   @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -395,7 +395,7 @@ public class PaymentResource extends ComboPaymentResource {
                                   @HeaderParam(HDR_COMMENT) final String comment,
                                   @javax.ws.rs.core.Context final UriInfo uriInfo,
                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-        return refundPaymentInternal(json, paymentIdStr, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+        return refundPaymentInternal(json, paymentId, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
     }
 
     @TimedResource(name = "refundPayment")
@@ -424,7 +424,7 @@ public class PaymentResource extends ComboPaymentResource {
     }
 
     private Response refundPaymentInternal(final PaymentTransactionJson json,
-                                           @Nullable final String paymentIdStr,
+                                           @Nullable final UUID paymentId,
                                            final List<String> paymentControlPluginNames,
                                            final List<String> pluginPropertiesString,
                                            final String createdBy,
@@ -441,7 +441,7 @@ public class PaymentResource extends ComboPaymentResource {
         final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
+        final Payment initialPayment = getPaymentByIdOrKey(paymentId, json.getPaymentExternalKey(), pluginProperties, callContext);
 
         final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
         final Currency currency = json.getCurrency() == null ? account.getCurrency() : Currency.valueOf(json.getCurrency());
@@ -469,7 +469,7 @@ public class PaymentResource extends ComboPaymentResource {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response voidPayment(final PaymentTransactionJson json,
-                                @PathParam("paymentId") final String paymentIdStr,
+                                @PathParam("paymentId") final UUID paymentId,
                                 @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                 @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -477,7 +477,7 @@ public class PaymentResource extends ComboPaymentResource {
                                 @HeaderParam(HDR_COMMENT) final String comment,
                                 @javax.ws.rs.core.Context final UriInfo uriInfo,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-        return voidPaymentInternal(json, paymentIdStr, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+        return voidPaymentInternal(json, paymentId, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
     }
 
     @TimedResource(name = "voidPayment")
@@ -504,7 +504,7 @@ public class PaymentResource extends ComboPaymentResource {
     }
 
     private Response voidPaymentInternal(final PaymentTransactionJson json,
-                                         @Nullable final String paymentIdStr,
+                                         @Nullable final UUID paymentId,
                                          final List<String> paymentControlPluginNames,
                                          final List<String> pluginPropertiesString,
                                          final String createdBy,
@@ -517,7 +517,7 @@ public class PaymentResource extends ComboPaymentResource {
         final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
+        final Payment initialPayment = getPaymentByIdOrKey(paymentId, json.getPaymentExternalKey(), pluginProperties, callContext);
 
         final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
 
@@ -544,7 +544,7 @@ public class PaymentResource extends ComboPaymentResource {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response chargebackPayment(final PaymentTransactionJson json,
-                                      @PathParam("paymentId") final String paymentIdStr,
+                                      @PathParam("paymentId") final UUID paymentId,
                                       @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                       @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -552,7 +552,7 @@ public class PaymentResource extends ComboPaymentResource {
                                       @HeaderParam(HDR_COMMENT) final String comment,
                                       @javax.ws.rs.core.Context final UriInfo uriInfo,
                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-        return chargebackPaymentInternal(json, paymentIdStr, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+        return chargebackPaymentInternal(json, paymentId, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
     }
 
     @TimedResource(name = "chargebackPayment")
@@ -580,7 +580,7 @@ public class PaymentResource extends ComboPaymentResource {
     }
 
     private Response chargebackPaymentInternal(final PaymentTransactionJson json,
-                                               @Nullable final String paymentIdStr,
+                                               @Nullable final UUID paymentId,
                                                final List<String> paymentControlPluginNames,
                                                final List<String> pluginPropertiesString,
                                                final String createdBy,
@@ -596,7 +596,7 @@ public class PaymentResource extends ComboPaymentResource {
         final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
+        final Payment initialPayment = getPaymentByIdOrKey(paymentId, json.getPaymentExternalKey(), pluginProperties, callContext);
 
         final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
         final Currency currency = json.getCurrency() == null ? account.getCurrency() : Currency.valueOf(json.getCurrency());
@@ -623,7 +623,7 @@ public class PaymentResource extends ComboPaymentResource {
                            @ApiResponse(code = 503, message = "Payment in unknown status, failed to receive gateway response"),
                            @ApiResponse(code = 504, message = "Payment operation timeout")})
     public Response chargebackReversalPayment(final PaymentTransactionJson json,
-                                              @PathParam("paymentId") final String paymentIdStr,
+                                              @PathParam("paymentId") final UUID paymentId,
                                               @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                               @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -631,7 +631,7 @@ public class PaymentResource extends ComboPaymentResource {
                                               @HeaderParam(HDR_COMMENT) final String comment,
                                               @javax.ws.rs.core.Context final UriInfo uriInfo,
                                               @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
-        return chargebackReversalPaymentInternal(json, paymentIdStr, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+        return chargebackReversalPaymentInternal(json, paymentId, paymentControlPluginNames, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
     }
 
     @TimedResource(name = "chargebackReversalPayment")
@@ -659,7 +659,7 @@ public class PaymentResource extends ComboPaymentResource {
     }
 
     private Response chargebackReversalPaymentInternal(final PaymentTransactionJson json,
-                                                       @Nullable final String paymentIdStr,
+                                                       @Nullable final UUID paymentId,
                                                        final List<String> paymentControlPluginNames,
                                                        final List<String> pluginPropertiesString,
                                                        final String createdBy,
@@ -672,7 +672,7 @@ public class PaymentResource extends ComboPaymentResource {
 
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
+        final Payment initialPayment = getPaymentByIdOrKey(paymentId, json.getPaymentExternalKey(), pluginProperties, callContext);
 
         final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
 
@@ -749,14 +749,14 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Cancels a scheduled payment attempt retry")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentTransactionId supplied")})
-    public Response cancelScheduledPaymentTransactionById(@PathParam("paymentTransactionId") final String paymentTransactionId,
+    public Response cancelScheduledPaymentTransactionById(@PathParam("paymentTransactionId") final UUID paymentTransactionId,
                                                           @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                           @HeaderParam(HDR_REASON) final String reason,
                                                           @HeaderParam(HDR_COMMENT) final String comment,
                                                           @javax.ws.rs.core.Context final UriInfo uriInfo,
                                                           @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        paymentApi.cancelScheduledPaymentTransaction(UUID.fromString(paymentTransactionId), callContext);
+        paymentApi.cancelScheduledPaymentTransaction(paymentTransactionId, callContext);
         return Response.status(Status.OK).build();
     }
 
@@ -767,7 +767,7 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Cancels a scheduled payment attempt retry")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentTransactionExternalKey supplied")})
-    public Response cancelScheduledPaymentTransactionByExternalKey(@QueryParam(QUERY_TRANSACTION_EXTERNAL_KEY) final String paymentTransactionExternalKey,
+    public Response cancelScheduledPaymentTransactionByExternalKey(@ApiParam(required=true) @QueryParam(QUERY_TRANSACTION_EXTERNAL_KEY) final String paymentTransactionExternalKey,
                                                                    @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                                                    @HeaderParam(HDR_REASON) final String reason,
                                                                    @HeaderParam(HDR_COMMENT) final String comment,
@@ -787,10 +787,10 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve payment custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(id), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(id, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @TimedResource
@@ -800,14 +800,14 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(id), customFields,
+        return super.createCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -818,13 +818,13 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(id), customFields,
+        return super.modifyCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -835,13 +835,13 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from payment payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(id), customFieldList,
+        return super.deleteCustomFields(id, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -852,12 +852,11 @@ public class PaymentResource extends ComboPaymentResource {
     @ApiOperation(value = "Retrieve payment payment tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"),
                            @ApiResponse(code = 404, message = "Invoice not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID paymentId,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_TAGS_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, PaymentApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final UUID paymentId = UUID.fromString(id);
         final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), tenantContext);
         return super.getTags(payment.getAccountId(), paymentId, auditMode, includedDeleted, tenantContext);
     }
@@ -869,14 +868,14 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to payment payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID paymentId,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.createTags(UUID.fromString(id), tagList, uriInfo,
+        return super.createTags(paymentId, tagList, uriInfo,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request), request);
     }
 
@@ -887,13 +886,13 @@ public class PaymentResource extends ComboPaymentResource {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from payment payment")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID paymentId,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.deleteTags(UUID.fromString(id), tagList,
+        return super.deleteTags(paymentId, tagList,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -903,7 +902,7 @@ public class PaymentResource extends ComboPaymentResource {
     }
 
     private Response completeTransactionInternalWithoutPayment(final PaymentTransactionJson json,
-                                                               @Nullable final String paymentIdStr,
+                                                               @Nullable final UUID paymentId,
                                                                final List<String> paymentControlPluginNames,
                                                                final Iterable<String> pluginPropertiesString,
                                                                final String createdBy,
@@ -919,7 +918,7 @@ public class PaymentResource extends ComboPaymentResource {
         final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
 
         final CallContext callContextNoAccountId = context.createCallContextNoAccountId(createdBy, reason, comment, request);
-        final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json == null ? null : json.getPaymentExternalKey(), pluginProperties, callContextNoAccountId);
+        final Payment initialPayment = getPaymentByIdOrKey(paymentId, json == null ? null : json.getPaymentExternalKey(), pluginProperties, callContextNoAccountId);
 
         return completeTransactionInternal(json, initialPayment, paymentControlPluginNames, pluginProperties, callContextNoAccountId, createdBy, reason, comment, uriInfo, request);
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java
index ffbd88c..936ba41 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginInfoResource.java
@@ -48,7 +48,7 @@ import io.swagger.annotations.ApiOperation;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.PLUGINS_INFO_PATH)
-@Api(value = JaxrsResource.PLUGINS_INFO_PATH, description = "Operations on plugins")
+@Api(value = JaxrsResource.PLUGINS_INFO_PATH, description = "Operations on plugins", tags="PluginInfo")
 public class PluginInfoResource extends JaxRsResourceBase {
 
     private final PluginsInfoApi pluginsInfoApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
index 60e55b5..5b85cf5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
@@ -65,7 +65,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.SECURITY_PATH)
-@Api(value = JaxrsResource.SECURITY_PATH, description = "Information about RBAC")
+@Api(value = JaxrsResource.SECURITY_PATH, description = "Information about RBAC", tags="Security")
 public class SecurityResource extends JaxRsResourceBase {
 
     private final SecurityApi securityApi;
@@ -147,7 +147,7 @@ public class SecurityResource extends JaxRsResourceBase {
     @GET
     @Produces(APPLICATION_JSON)
     @Path("/users/{username:" + ANYTHING_PATTERN + "}/roles")
-    @ApiOperation(value = "Get roles associated to a user")
+    @ApiOperation(value = "Get roles associated to a user", response = UserRolesJson.class)
     public Response getUserRoles(@PathParam("username") final String username,
                                  @javax.ws.rs.core.Context final HttpServletRequest request,
                                  @javax.ws.rs.core.Context final UriInfo uriInfo) throws SecurityApiException {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
index ae71972..5f8cf95 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
@@ -76,7 +76,8 @@ import org.killbill.billing.events.PaymentErrorInternalEvent;
 import org.killbill.billing.events.PaymentInfoInternalEvent;
 import org.killbill.billing.events.PaymentPluginErrorInternalEvent;
 import org.killbill.billing.jaxrs.json.BlockingStateJson;
-import org.killbill.billing.jaxrs.json.BulkBaseSubscriptionAndAddOnsJson;
+import org.killbill.billing.jaxrs.json.BulkSubscriptionsBundleJson;
+import org.killbill.billing.jaxrs.json.BundleJson;
 import org.killbill.billing.jaxrs.json.CustomFieldJson;
 import org.killbill.billing.jaxrs.json.PhasePriceOverrideJson;
 import org.killbill.billing.jaxrs.json.SubscriptionJson;
@@ -115,7 +116,7 @@ import io.swagger.annotations.ApiResponses;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.SUBSCRIPTIONS_PATH)
-@Api(value = JaxrsResource.SUBSCRIPTIONS_PATH, description = "Operations on subscriptions")
+@Api(value = JaxrsResource.SUBSCRIPTIONS_PATH, description = "Operations on subscriptions", tags="Subscription")
 public class SubscriptionResource extends JaxRsResourceBase {
 
     private static final Logger log = LoggerFactory.getLogger(SubscriptionResource.class);
@@ -150,12 +151,11 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve a subscription by id", response = SubscriptionJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Subscription not found")})
-    public Response getEntitlement(@PathParam("subscriptionId") final String subscriptionId,
+    public Response getEntitlement(@PathParam("subscriptionId") final UUID subscriptionId,
                                    @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
-        final UUID uuid = UUID.fromString(subscriptionId);
         final TenantContext context = this.context.createTenantContextNoAccountId(request);
-        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(uuid, context);
+        final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(subscriptionId, context);
         final Account account = accountUserApi.getAccountById(subscription.getAccountId(), context);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(subscription.getAccountId(), auditMode.getLevel(), context);
         final SubscriptionJson json = new SubscriptionJson(subscription, account.getCurrency(), accountAuditLogs);
@@ -228,7 +228,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
             private UUID getBundleIdForAddOnCreation(final SubscriptionJson entitlement) throws SubscriptionApiException {
 
                 if (entitlement.getBundleId() != null) {
-                    return UUID.fromString(entitlement.getBundleId());
+                    return entitlement.getBundleId();
                 }
                 // If user only specified the externalKey we need to fech the bundle (expensive operation) to extract the bundleId
                 final SubscriptionBundle bundle = subscriptionApi.getActiveSubscriptionBundleForExternalKey(entitlement.getExternalKey(), callContext);
@@ -255,7 +255,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Path("/createEntitlementWithAddOns")
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
-    @ApiOperation(value = "Create an entitlement with addOn products")
+    @ApiOperation(value = "Create an entitlement with addOn products", response = BundleJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid entitlement supplied")})
     public Response createEntitlementWithAddOns(final List<SubscriptionJson> entitlements,
                                                 @QueryParam(QUERY_REQUESTED_DT) final String requestedDate, /* This is deprecated, only used for backward compatibility */
@@ -271,7 +271,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                                 @HeaderParam(HDR_COMMENT) final String comment,
                                                 @javax.ws.rs.core.Context final HttpServletRequest request,
                                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
-        final List<BulkBaseSubscriptionAndAddOnsJson> entitlementsWithAddOns = ImmutableList.of(new BulkBaseSubscriptionAndAddOnsJson(entitlements));
+        final List<BulkSubscriptionsBundleJson> entitlementsWithAddOns = ImmutableList.of(new BulkSubscriptionsBundleJson(entitlements));
         return createEntitlementsWithAddOnsInternal(entitlementsWithAddOns, requestedDate, entitlementDate, billingDate, isMigrated, renameKeyIfExistsAndUnused, callCompletion, timeoutSec, pluginPropertiesString, createdBy, reason, comment, request, uriInfo, ObjectType.BUNDLE);
     }
 
@@ -280,9 +280,9 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Path("/createEntitlementsWithAddOns")
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
-    @ApiOperation(value = "Create multiple entitlements with addOn products")
+    @ApiOperation(value = "Create multiple entitlements with addOn products", response = BundleJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid entitlements supplied")})
-    public Response createEntitlementsWithAddOns(final List<BulkBaseSubscriptionAndAddOnsJson> entitlementsWithAddOns,
+    public Response createEntitlementsWithAddOns(final List<BulkSubscriptionsBundleJson> entitlementsWithAddOns,
                                                 @QueryParam(QUERY_REQUESTED_DT) final String requestedDate, /* This is deprecated, only used for backward compatibility */
                                                 @QueryParam(QUERY_ENTITLEMENT_REQUESTED_DT) final String entitlementDate,
                                                 @QueryParam(QUERY_BILLING_REQUESTED_DT) final String billingDate,
@@ -300,7 +300,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     }
 
 
-    public Response createEntitlementsWithAddOnsInternal(final List<BulkBaseSubscriptionAndAddOnsJson> entitlementsWithAddOns,
+    public Response createEntitlementsWithAddOnsInternal(final List<BulkSubscriptionsBundleJson> entitlementsWithAddOns,
                                                  final String requestedDate,
                                                  final String entitlementDate,
                                                  final String billingDate,
@@ -322,10 +322,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final Account account = accountUserApi.getAccountById(UUID.fromString(entitlementsWithAddOns.get(0).getBaseEntitlementAndAddOns().get(0).getAccountId()), callContext);
+        final Account account = accountUserApi.getAccountById(entitlementsWithAddOns.get(0).getBaseEntitlementAndAddOns().get(0).getAccountId(), callContext);
 
         final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
-        for (BulkBaseSubscriptionAndAddOnsJson bulkBaseEntitlementWithAddOns : entitlementsWithAddOns) {
+        for (BulkSubscriptionsBundleJson bulkBaseEntitlementWithAddOns : entitlementsWithAddOns) {
             final Iterable<SubscriptionJson> baseEntitlements = Iterables.filter(
                     bulkBaseEntitlementWithAddOns.getBaseEntitlementAndAddOns(), new Predicate<SubscriptionJson>() {
                         @Override
@@ -503,15 +503,14 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiOperation(value = "Un-cancel an entitlement")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Entitlement not found")})
-    public Response uncancelEntitlementPlan(@PathParam("subscriptionId") final String subscriptionId,
+    public Response uncancelEntitlementPlan(@PathParam("subscriptionId") final UUID subscriptionId,
                                             @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                             @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                             @HeaderParam(HDR_REASON) final String reason,
                                             @HeaderParam(HDR_COMMENT) final String comment,
                                             @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID uuid = UUID.fromString(subscriptionId);
-        final Entitlement current = entitlementApi.getEntitlementForId(uuid, context.createCallContextNoAccountId(createdBy, reason, comment, request));
+        final Entitlement current = entitlementApi.getEntitlementForId(subscriptionId, context.createCallContextNoAccountId(createdBy, reason, comment, request));
         current.uncancelEntitlement(pluginProperties, context.createCallContextNoAccountId(createdBy, reason, comment, request));
         return Response.status(Status.OK).build();
     }
@@ -523,15 +522,14 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiOperation(value = "Undo a pending change plan on an entitlement")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Entitlement not found")})
-    public Response undoChangeEntitlementPlan(@PathParam("subscriptionId") final String subscriptionId,
+    public Response undoChangeEntitlementPlan(@PathParam("subscriptionId") final UUID subscriptionId,
                                             @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                             @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                             @HeaderParam(HDR_REASON) final String reason,
                                             @HeaderParam(HDR_COMMENT) final String comment,
                                             @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID uuid = UUID.fromString(subscriptionId);
-        final Entitlement current = entitlementApi.getEntitlementForId(uuid, context.createCallContextNoAccountId(createdBy, reason, comment, request));
+        final Entitlement current = entitlementApi.getEntitlementForId(subscriptionId, context.createCallContextNoAccountId(createdBy, reason, comment, request));
         current.undoChangePlan(pluginProperties, context.createCallContextNoAccountId(createdBy, reason, comment, request));
         return Response.status(Status.OK).build();
     }
@@ -545,7 +543,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Entitlement not found")})
     public Response changeEntitlementPlan(final SubscriptionJson entitlement,
-                                          @PathParam("subscriptionId") final String subscriptionId,
+                                          @PathParam("subscriptionId") final UUID subscriptionId,
                                           @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                           @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
                                           @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
@@ -572,9 +570,8 @@ public class SubscriptionResource extends JaxRsResourceBase {
             @Override
             public Response doOperation(final CallContext ctx) throws EntitlementApiException, InterruptedException,
                                                                       TimeoutException, AccountApiException {
-                final UUID uuid = UUID.fromString(subscriptionId);
 
-                final Entitlement current = entitlementApi.getEntitlementForId(uuid, callContext);
+                final Entitlement current = entitlementApi.getEntitlementForId(subscriptionId, callContext);
                 final LocalDate inputLocalDate = toLocalDate(requestedDate);
                 final Entitlement newEntitlement;
 
@@ -626,7 +623,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Subscription not found")})
     public Response addSubscriptionBlockingState(final BlockingStateJson json,
-                                                 @PathParam(ID_PARAM_NAME) final String id,
+                                                 @PathParam(ID_PARAM_NAME) final UUID id,
                                                  @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                                  @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -644,7 +641,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiOperation(value = "Cancel an entitlement plan")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Entitlement not found")})
-    public Response cancelEntitlementPlan(@PathParam("subscriptionId") final String subscriptionId,
+    public Response cancelEntitlementPlan(@PathParam("subscriptionId") final UUID subscriptionId,
                                           @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
                                           @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
                                           @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("5") final long timeoutSec,
@@ -668,9 +665,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
             public Response doOperation(final CallContext ctx)
                     throws EntitlementApiException, InterruptedException,
                            TimeoutException, AccountApiException, SubscriptionApiException {
-                final UUID uuid = UUID.fromString(subscriptionId);
-
-                final Entitlement current = entitlementApi.getEntitlementForId(uuid, ctx);
+                final Entitlement current = entitlementApi.getEntitlementForId(subscriptionId, ctx);
                 final LocalDate inputLocalDate = toLocalDate(requestedDate);
                 final Entitlement newEntitlement;
                 if (billingPolicyString == null && entitlementPolicyString == null) {
@@ -718,7 +713,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiOperation(value = "Update the BCD associated to a subscription")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid entitlement supplied")})
     public Response updateSubscriptionBCD(final SubscriptionJson json,
-                                          @PathParam(ID_PARAM_NAME) final String id,
+                                          @PathParam(ID_PARAM_NAME) final UUID subscriptionId,
                                           @QueryParam(QUERY_ENTITLEMENT_EFFECTIVE_FROM_DT) final String effectiveFromDateStr,
                                           @QueryParam(QUERY_FORCE_NEW_BCD_WITH_PAST_EFFECTIVE_DATE) @DefaultValue("false") final Boolean forceNewBcdWithPastEffectiveDate,
                                           @HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -733,8 +728,6 @@ public class SubscriptionResource extends JaxRsResourceBase {
         LocalDate effectiveFromDate = toLocalDate(effectiveFromDateStr);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final UUID subscriptionId = UUID.fromString(id);
-
         final Entitlement entitlement = entitlementApi.getEntitlementForId(subscriptionId, callContext);
         if (effectiveFromDateStr != null) {
             final Account account = accountUserApi.getAccountById(entitlement.getAccountId(), callContext);
@@ -867,10 +860,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve subscription custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(id), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(id, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @POST
@@ -879,14 +872,14 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to subscription")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(id), customFields,
+        return super.createCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -896,13 +889,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to subscription")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(id), customFields,
+        return super.modifyCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -912,14 +905,14 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from subscription")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(id), customFieldList,
+        return super.deleteCustomFields(id, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -929,11 +922,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve subscription tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
                            @ApiResponse(code = 404, message = "Subscription not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String subscriptionIdString,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID subscriptionId,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, SubscriptionApiException {
-        final UUID subscriptionId = UUID.fromString(subscriptionIdString);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(subscriptionId, tenantContext);
         return super.getTags(subscription.getAccountId(), subscriptionId, auditMode, includedDeleted, tenantContext);
@@ -945,14 +937,14 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to subscription")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.createTags(UUID.fromString(id), tagList, uriInfo,
+        return super.createTags(id, tagList, uriInfo,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request), request);
     }
 
@@ -962,13 +954,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from subscription")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.deleteTags(UUID.fromString(id), tagList,
+        return super.deleteTags(id, tagList,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -980,12 +972,12 @@ public class SubscriptionResource extends JaxRsResourceBase {
     private Account getAccountFromSubscriptionJson(final SubscriptionJson entitlementJson, final CallContext callContext) throws SubscriptionApiException, AccountApiException, EntitlementApiException {
         final UUID accountId;
         if (entitlementJson.getAccountId() != null) {
-            accountId = UUID.fromString(entitlementJson.getAccountId());
+            accountId = entitlementJson.getAccountId();
         } else if (entitlementJson.getSubscriptionId() != null) {
-            final Entitlement entitlement = entitlementApi.getEntitlementForId(UUID.fromString(entitlementJson.getSubscriptionId()), callContext);
+            final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementJson.getSubscriptionId(), callContext);
             accountId = entitlement.getAccountId();
         } else {
-            final SubscriptionBundle subscriptionBundle = subscriptionApi.getSubscriptionBundle(UUID.fromString(entitlementJson.getBundleId()), callContext);
+            final SubscriptionBundle subscriptionBundle = subscriptionApi.getSubscriptionBundle(entitlementJson.getBundleId(), callContext);
             accountId = subscriptionBundle.getAccountId();
         }
         return accountUserApi.getAccountById(accountId, callContext);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
index efa5c24..7f5d997 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
@@ -64,7 +64,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.TAG_DEFINITIONS_PATH)
-@Api(value = JaxrsResource.TAG_DEFINITIONS_PATH, description = "Operations on tag definitions")
+@Api(value = JaxrsResource.TAG_DEFINITIONS_PATH, description = "Operations on tag definitions", tags="TagDefinition")
 public class TagDefinitionResource extends JaxRsResourceBase {
 
     @Inject
@@ -104,11 +104,11 @@ public class TagDefinitionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve a tag definition", response = TagDefinitionJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tagDefinitionId supplied")})
-    public Response getTagDefinition(@PathParam("tagDefinitionId") final String tagDefId,
+    public Response getTagDefinition(@PathParam("tagDefinitionId") final UUID tagDefId,
                                      @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final TagDefinition tagDefinition = tagUserApi.getTagDefinition(UUID.fromString(tagDefId), tenantContext);
+        final TagDefinition tagDefinition = tagUserApi.getTagDefinition(tagDefId, tenantContext);
         final List<AuditLog> auditLogs = auditUserApi.getAuditLogs(tagDefinition.getId(), ObjectType.TAG_DEFINITION, auditMode.getLevel(), tenantContext);
         final TagDefinitionJson json = new TagDefinitionJson(tagDefinition, auditLogs);
         return Response.status(Status.OK).entity(json).build();
@@ -144,12 +144,12 @@ public class TagDefinitionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Delete a tag definition")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tagDefinitionId supplied")})
-    public Response deleteTagDefinition(@PathParam("tagDefinitionId") final String tagDefId,
+    public Response deleteTagDefinition(@PathParam("tagDefinitionId") final UUID tagDefId,
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
                                         @HeaderParam(HDR_COMMENT) final String comment,
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
-        tagUserApi.deleteTagDefinition(UUID.fromString(tagDefId), context.createCallContextNoAccountId(createdBy, reason, comment, request));
+        tagUserApi.deleteTagDefinition(tagDefId, context.createCallContextNoAccountId(createdBy, reason, comment, request));
         return Response.status(Status.NO_CONTENT).build();
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
index c634f84..e194d3c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
@@ -61,7 +61,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.TAGS_PATH)
-@Api(value = JaxrsResource.TAGS_PATH, description = "Operations on tags")
+@Api(value = JaxrsResource.TAGS_PATH, description = "Operations on tags", tags="Tag")
 public class TagResource extends JaxRsResourceBase {
 
     @Inject
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
index 664fcea..33fa7d7 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
@@ -75,7 +75,7 @@ import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
 
 @Singleton
 @Path(JaxrsResource.TENANTS_PATH)
-@Api(value = JaxrsResource.TENANTS_PATH, description = "Operations on tenants")
+@Api(value = JaxrsResource.TENANTS_PATH, description = "Operations on tenants", tags="Tenant")
 public class TenantResource extends JaxRsResourceBase {
 
     private final TenantUserApi tenantApi;
@@ -104,8 +104,8 @@ public class TenantResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve a tenant by id", response = TenantJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tenantId supplied"),
                            @ApiResponse(code = 404, message = "Tenant not found")})
-    public Response getTenant(@PathParam("tenantId") final String tenantId) throws TenantApiException {
-        final Tenant tenant = tenantApi.getTenantById(UUID.fromString(tenantId));
+    public Response getTenant(@PathParam("tenantId") final UUID tenantId) throws TenantApiException {
+        final Tenant tenant = tenantApi.getTenantById(tenantId);
         return Response.status(Status.OK).entity(new TenantJson(tenant)).build();
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
index 5e01d3c..13e2206 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
@@ -90,7 +90,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 //
 //
 @Path(JaxrsResource.TEST_PATH)
-@Api(value = JaxrsResource.TEST_PATH, description = "Operations for testing")
+@Api(value = JaxrsResource.TEST_PATH, description = "Operations for testing", hidden=true)
 public class TestResource extends JaxRsResourceBase {
 
     private static final Logger log = LoggerFactory.getLogger(TestResource.class);
@@ -181,7 +181,6 @@ public class TestResource extends JaxRsResourceBase {
 
         final ClockMock testClock = getClockMock();
         if (requestedClockDate == null) {
-            log.info("************      RESETTING CLOCK to " + clock.getUTCNow());
             testClock.resetDeltaFromReality();
         } else {
             final DateTime newTime = DATE_TIME_FORMATTER.parseDateTime(requestedClockDate).toDateTime(DateTimeZone.UTC);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
index 414b01d..31f6522 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
@@ -73,7 +73,7 @@ import io.swagger.annotations.ApiResponses;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.PAYMENT_TRANSACTIONS_PATH)
-@Api(value = JaxrsResource.PAYMENT_TRANSACTIONS_PATH, description = "Operations on payment transactions")
+@Api(value = JaxrsResource.PAYMENT_TRANSACTIONS_PATH, description = "Operations on payment transactions", tags="PaymentTransaction")
 public class TransactionResource extends JaxRsResourceBase {
 
     private static final String ID_PARAM_NAME = "transactionId";
@@ -96,16 +96,15 @@ public class TransactionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve a payment by transaction id", response = PaymentJson.class)
     @ApiResponses(value = {@ApiResponse(code = 404, message = "Payment not found")})
-    public Response getPaymentByTransactionId(@PathParam("transactionId") final String transactionIdStr,
+    public Response getPaymentByTransactionId(@PathParam("transactionId") final UUID transactionId,
                                               @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
                                               @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
                                               @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
                                               @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                               @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
-        final UUID transactionIdId = UUID.fromString(transactionIdStr);
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final Payment payment = paymentApi.getPaymentByTransactionId(transactionIdId, withPluginInfo, withAttempts, pluginProperties, tenantContext);
+        final Payment payment = paymentApi.getPaymentByTransactionId(transactionId, withPluginInfo, withAttempts, pluginProperties, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
         final PaymentJson result = new PaymentJson(payment, accountAuditLogs);
         return Response.status(Response.Status.OK).entity(result).build();
@@ -120,7 +119,7 @@ public class TransactionResource extends JaxRsResourceBase {
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentId supplied"),
                            @ApiResponse(code = 404, message = "Account or Payment not found")})
     public Response notifyStateChanged(final PaymentTransactionJson json,
-                                       @PathParam("transactionId") final String transactionIdStr,
+                                       @PathParam("transactionId") final UUID transactionId,
                                        @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
@@ -134,12 +133,12 @@ public class TransactionResource extends JaxRsResourceBase {
         final PaymentOptions paymentOptions = createControlPluginApiPaymentOptions(paymentControlPluginNames);
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
 
-        final UUID paymentId = UUID.fromString(json.getPaymentId());
+        final UUID paymentId = json.getPaymentId();
         final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
 
         final boolean success = TransactionStatus.SUCCESS.name().equals(json.getStatus());
-        final Payment result = paymentApi.notifyPendingTransactionOfStateChangedWithPaymentControl(account, UUID.fromString(transactionIdStr), success, paymentOptions, callContext);
+        final Payment result = paymentApi.notifyPendingTransactionOfStateChangedWithPaymentControl(account, transactionId, success, paymentOptions, callContext);
 
         return uriBuilder.buildResponse(uriInfo, PaymentResource.class, "getPayment", result.getId(), request);
     }
@@ -151,10 +150,10 @@ public class TransactionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve payment transaction custom fields", response = CustomFieldJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid transaction id supplied")})
-    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                     @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        return super.getCustomFields(UUID.fromString(id), auditMode, context.createTenantContextNoAccountId(request));
+        return super.getCustomFields(id, auditMode, context.createTenantContextNoAccountId(request));
     }
 
     @TimedResource
@@ -164,14 +163,14 @@ public class TransactionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add custom fields to payment transaction")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid transaction id supplied")})
-    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request,
                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
-        return super.createCustomFields(UUID.fromString(id), customFields,
+        return super.createCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request), uriInfo, request);
     }
 
@@ -183,13 +182,13 @@ public class TransactionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Modify custom fields to payment transaction")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid transaction id supplied")})
-    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response modifyCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        final List<CustomFieldJson> customFields,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.modifyCustomFields(UUID.fromString(id), customFields,
+        return super.modifyCustomFields(id, customFields,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -201,13 +200,13 @@ public class TransactionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove custom fields from payment transaction")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid transaction id supplied")})
-    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final UUID id,
                                        @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
-        return super.deleteCustomFields(UUID.fromString(id), customFieldList,
+        return super.deleteCustomFields(id, customFieldList,
                                         context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
@@ -218,13 +217,13 @@ public class TransactionResource extends JaxRsResourceBase {
     @ApiOperation(value = "Retrieve payment transaction tags", response = TagJson.class, responseContainer = "List")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid transaction id supplied"),
                            @ApiResponse(code = 404, message = "Invoice not found")})
-    public Response getTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response getTags(@PathParam(ID_PARAM_NAME) final UUID id,
                             @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                             @QueryParam(QUERY_TAGS_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, PaymentApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
-        final Payment payment = paymentApi.getPaymentByTransactionId(UUID.fromString(id), false, false, ImmutableList.<PluginProperty>of(), tenantContext);
-        return super.getTags(payment.getAccountId(), UUID.fromString(id), auditMode, includedDeleted, tenantContext);
+        final Payment payment = paymentApi.getPaymentByTransactionId(id, false, false, ImmutableList.<PluginProperty>of(), tenantContext);
+        return super.getTags(payment.getAccountId(), id, auditMode, includedDeleted, tenantContext);
     }
 
     @TimedResource
@@ -234,14 +233,14 @@ public class TransactionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Add tags to payment transaction")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid transaction id supplied")})
-    public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response createTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final UriInfo uriInfo,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.createTags(UUID.fromString(id), tagList, uriInfo,
+        return super.createTags(id, tagList, uriInfo,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request), request);
     }
 
@@ -252,13 +251,13 @@ public class TransactionResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Remove tags from payment transaction")
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid transaction id supplied")})
-    public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
+    public Response deleteTags(@PathParam(ID_PARAM_NAME) final UUID id,
                                @QueryParam(QUERY_TAGS) final String tagList,
                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                @HeaderParam(HDR_REASON) final String reason,
                                @HeaderParam(HDR_COMMENT) final String comment,
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
-        return super.deleteTags(UUID.fromString(id), tagList,
+        return super.deleteTags(id, tagList,
                                 context.createCallContextNoAccountId(createdBy, reason, comment, request));
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
index 85029aa..1e51050 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
@@ -72,7 +72,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Singleton
 @Path(JaxrsResource.USAGES_PATH)
-@Api(value = JaxrsResource.USAGES_PATH, description = "Operations on usage")
+@Api(value = JaxrsResource.USAGES_PATH, description = "Operations on usage", tags="Usage")
 public class UsageResource extends JaxRsResourceBase {
 
     private final UsageUserApi usageUserApi;
@@ -123,7 +123,7 @@ public class UsageResource extends JaxRsResourceBase {
         }
         final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
         // Verify subscription exists..
-        final Entitlement entitlement = entitlementApi.getEntitlementForId(UUID.fromString(json.getSubscriptionId()), callContext);
+        final Entitlement entitlement = entitlementApi.getEntitlementForId(json.getSubscriptionId(), callContext);
         if (entitlement.getState() != EntitlementState.ACTIVE) {
             return Response.status(Status.BAD_REQUEST).build();
         }
@@ -139,7 +139,7 @@ public class UsageResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve usage for a subscription and unit type", response = RolledUpUsageJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Missing start date or end date")})
-    public Response getUsage(@PathParam("subscriptionId") final String subscriptionId,
+    public Response getUsage(@PathParam("subscriptionId") final UUID subscriptionId,
                              @PathParam("unitType") final String unitType,
                              @QueryParam(QUERY_START_DATE) final String startDate,
                              @QueryParam(QUERY_END_DATE) final String endDate,
@@ -152,7 +152,7 @@ public class UsageResource extends JaxRsResourceBase {
         final LocalDate usageStartDate = LOCAL_DATE_FORMATTER.parseLocalDate(startDate);
         final LocalDate usageEndDate = LOCAL_DATE_FORMATTER.parseLocalDate(endDate);
 
-        final RolledUpUsage usage = usageUserApi.getUsageForSubscription(UUID.fromString(subscriptionId), unitType, usageStartDate, usageEndDate, tenantContext);
+        final RolledUpUsage usage = usageUserApi.getUsageForSubscription(subscriptionId, unitType, usageStartDate, usageEndDate, tenantContext);
         final RolledUpUsageJson result = new RolledUpUsageJson(usage);
         return Response.status(Status.OK).entity(result).build();
     }
@@ -163,7 +163,7 @@ public class UsageResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @ApiOperation(value = "Retrieve usage for a subscription", response = RolledUpUsageJson.class)
     @ApiResponses(value = {@ApiResponse(code = 400, message = "Missing start date or end date")})
-    public Response getAllUsage(@PathParam("subscriptionId") final String subscriptionId,
+    public Response getAllUsage(@PathParam("subscriptionId") final UUID subscriptionId,
                                 @QueryParam(QUERY_START_DATE) final String startDate,
                                 @QueryParam(QUERY_END_DATE) final String endDate,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) {
@@ -178,7 +178,7 @@ public class UsageResource extends JaxRsResourceBase {
 
         // The current JAXRS API only allows to look for one transition
         final List<LocalDate> startEndDate = ImmutableList.<LocalDate>builder().add(usageStartDate).add(usageEndDate).build();
-        final List<RolledUpUsage> usage = usageUserApi.getAllUsageForSubscription(UUID.fromString(subscriptionId), startEndDate, tenantContext);
+        final List<RolledUpUsage> usage = usageUserApi.getAllUsageForSubscription(subscriptionId, startEndDate, tenantContext);
         final RolledUpUsageJson result = new RolledUpUsageJson(usage.get(0));
         return Response.status(Status.OK).entity(result).build();
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/Context.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/Context.java
index a920744..73ffa05 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/Context.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/Context.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2014 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -93,7 +93,7 @@ public class Context {
         return tenantContext;
     }
 
-    // Use REQUEST_ID_HEADER if this is provided and lloks like a UUID, if not allocate a random one.
+    // Use REQUEST_ID_HEADER if this is provided and looks like a UUID, if not allocate a random one.
     public static  UUID getOrCreateUserToken() {
         UUID userToken;
         if (Request.getPerThreadRequestData().getRequestId() != null) {
@@ -118,6 +118,11 @@ public class Context {
         }
     }
 
+    private void populateMDCContext(final CallContext callContext) {
+        // InternalCallContextFactory will do it for us
+        internalCallContextFactory.createInternalCallContextWithoutAccountRecordId(callContext);
+    }
+
     private void populateMDCContext(final TenantContext tenantContext) {
         // InternalCallContextFactory will do it for us
         internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(tenantContext);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountEmailJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountEmailJson.java
index 2161e12..71419b0 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountEmailJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountEmailJson.java
@@ -28,7 +28,7 @@ public class TestAccountEmailJson extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String accountId = UUID.randomUUID().toString();
+        final UUID accountId = UUID.randomUUID();
         final String email = UUID.randomUUID().toString();
 
         final AccountEmailJson accountEmailJson = new AccountEmailJson(accountId, email);
@@ -46,7 +46,7 @@ public class TestAccountEmailJson extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testToAccountEmail() throws Exception {
-        final String accountId = UUID.randomUUID().toString();
+        final UUID accountId = UUID.randomUUID();
         final String email = UUID.randomUUID().toString();
 
         final AccountEmailJson accountEmailJson = new AccountEmailJson(accountId, email);
@@ -54,7 +54,7 @@ public class TestAccountEmailJson extends JaxrsTestSuiteNoDB {
         Assert.assertEquals(accountEmailJson.getEmail(), email);
 
         final AccountEmail accountEmail = accountEmailJson.toAccountEmail(UUID.randomUUID());
-        Assert.assertEquals(accountEmail.getAccountId().toString(), accountId);
+        Assert.assertEquals(accountEmail.getAccountId(), accountId);
         Assert.assertEquals(accountEmail.getEmail(), email);
     }
 }
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java
index 08b1186..1e06a8e 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestAccountJson.java
@@ -32,14 +32,14 @@ public class TestAccountJson extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String accountId = UUID.randomUUID().toString();
+        final UUID accountId = UUID.randomUUID();
         final String name = UUID.randomUUID().toString();
         final Integer length = 12;
         final String externalKey = UUID.randomUUID().toString();
         final String email = UUID.randomUUID().toString();
         final Integer billCycleDayLocal = 6;
         final String currency = UUID.randomUUID().toString();
-        final String paymentMethodId = UUID.randomUUID().toString();
+        final UUID paymentMethodId = UUID.randomUUID();
         final DateTime referenceTime = new DateTime();
         final String timeZone = UUID.randomUUID().toString();
         final String address1 = UUID.randomUUID().toString();
@@ -54,7 +54,7 @@ public class TestAccountJson extends JaxrsTestSuiteNoDB {
         final String notes = UUID.randomUUID().toString();
         final Boolean isMigrated = true;
         final Boolean isNotifiedForInvoice = false;
-        final String parentAccountId = UUID.randomUUID().toString();
+        final UUID parentAccountId = UUID.randomUUID();
 
         final AccountJson accountJson = new AccountJson(accountId, name, length, externalKey,
                                                         email, billCycleDayLocal, currency, parentAccountId, true, paymentMethodId,
@@ -127,12 +127,12 @@ public class TestAccountJson extends JaxrsTestSuiteNoDB {
         Assert.assertEquals(accountJson.getEmail(), account.getEmail());
         Assert.assertEquals(accountJson.getExternalKey(), account.getExternalKey());
         Assert.assertEquals(accountJson.getName(), account.getName());
-        Assert.assertEquals(accountJson.getPaymentMethodId(), account.getPaymentMethodId().toString());
+        Assert.assertEquals(accountJson.getPaymentMethodId(), account.getPaymentMethodId());
         Assert.assertEquals(accountJson.getPhone(), account.getPhone());
         Assert.assertEquals(accountJson.isMigrated(), account.isMigrated());
         Assert.assertEquals(accountJson.isNotifiedForInvoices(), account.isNotifiedForInvoices());
         Assert.assertEquals(accountJson.getState(), account.getStateOrProvince());
         Assert.assertEquals(accountJson.getTimeZone(), account.getTimeZone().toString());
-        Assert.assertEquals(accountJson.getParentAccountId(), account.getParentAccountId().toString());
+        Assert.assertEquals(accountJson.getParentAccountId(), account.getParentAccountId());
     }
 }
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
index dd67ebf..2b3e45c 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
@@ -37,12 +37,12 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String someUUID = UUID.randomUUID().toString();
+        final UUID someUUID = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
         final List<AuditLogJson> auditLogs = createAuditLogsJson(clock.getUTCNow());
 
-        final EventSubscriptionJson event = new EventSubscriptionJson(UUID.randomUUID().toString(),
+        final EventSubscriptionJson event = new EventSubscriptionJson(UUID.randomUUID(),
                                                                       BillingPeriod.NO_BILLING_PERIOD.toString(),
                                                                       new LocalDate(),
                                                                       UUID.randomUUID().toString(),
@@ -58,9 +58,9 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuiteNoDB {
 
         final PhasePriceOverrideJson priceOverride = new PhasePriceOverrideJson(null, null, "somePhaseType", BigDecimal.ONE, null, null);
 
-        final SubscriptionJson subscription = new SubscriptionJson(UUID.randomUUID().toString(),
-                                                                   UUID.randomUUID().toString(),
-                                                                   UUID.randomUUID().toString(),
+        final SubscriptionJson subscription = new SubscriptionJson(UUID.randomUUID(),
+                                                                   UUID.randomUUID(),
+                                                                   UUID.randomUUID(),
                                                                    externalKey,
                                                                    new LocalDate(),
                                                                    UUID.randomUUID().toString(),
@@ -80,8 +80,8 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuiteNoDB {
                                                                    ImmutableList.of(priceOverride),
                                                                    auditLogs);
 
-        final BundleJson bundleJson = new BundleJson(someUUID, bundleId.toString(), externalKey, ImmutableList.<SubscriptionJson>of(subscription), null, auditLogs);
-        Assert.assertEquals(bundleJson.getBundleId(), bundleId.toString());
+        final BundleJson bundleJson = new BundleJson(someUUID, bundleId, externalKey, ImmutableList.<SubscriptionJson>of(subscription), null, auditLogs);
+        Assert.assertEquals(bundleJson.getBundleId(), bundleId);
         Assert.assertEquals(bundleJson.getExternalKey(), externalKey);
         Assert.assertEquals(bundleJson.getSubscriptions().size(), 1);
         Assert.assertEquals(bundleJson.getAuditLogs(), auditLogs);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleTimelineJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleTimelineJson.java
index 114d0fc..18e2914 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleTimelineJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestBundleTimelineJson.java
@@ -33,7 +33,7 @@ public class TestBundleTimelineJson extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final EventSubscriptionJson event = new EventSubscriptionJson(UUID.randomUUID().toString(),
+        final EventSubscriptionJson event = new EventSubscriptionJson(UUID.randomUUID(),
                                                                       BillingPeriod.NO_BILLING_PERIOD.toString(),
                                                                       new LocalDate(),
                                                                       UUID.randomUUID().toString(),
@@ -46,8 +46,8 @@ public class TestBundleTimelineJson extends JaxrsTestSuiteNoDB {
                                                                       UUID.randomUUID().toString(),
                                                                       UUID.randomUUID().toString(),
                                                                       null);
-        final BundleTimelineJson bundleTimelineJson = new BundleTimelineJson(UUID.randomUUID().toString(),
-                                                                             UUID.randomUUID().toString(),
+        final BundleTimelineJson bundleTimelineJson = new BundleTimelineJson(UUID.randomUUID(),
+                                                                             UUID.randomUUID(),
                                                                              UUID.randomUUID().toString(),
                                                                              ImmutableList.<EventSubscriptionJson>of(event),
                                                                              null);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java
index 422a0f1..265c3e4 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java
@@ -36,10 +36,10 @@ public class TestCreditJson extends JaxrsTestSuiteNoDB {
     public void testJson() throws Exception {
         final BigDecimal creditAmount = BigDecimal.TEN;
         final Currency currency = Currency.AED;
-        final String invoiceId = UUID.randomUUID().toString();
+        final UUID invoiceId = UUID.randomUUID();
         final String invoiceNumber = UUID.randomUUID().toString();
         final LocalDate effectiveDate = clock.getUTCToday();
-        final String accountId = UUID.randomUUID().toString();
+        final UUID accountId = UUID.randomUUID();
         final List<AuditLogJson> auditLogs = createAuditLogsJson(clock.getUTCNow());
         final CreditJson creditJson = new CreditJson(creditAmount, currency.name(), invoiceId, invoiceNumber, effectiveDate,
                                                      accountId, null, auditLogs);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCustomFieldJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCustomFieldJson.java
index 36edc38..792a1a2 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCustomFieldJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCustomFieldJson.java
@@ -28,8 +28,8 @@ public class TestCustomFieldJson extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String customFieldId = UUID.randomUUID().toString();
-        final String objectId = UUID.randomUUID().toString();
+        final UUID customFieldId = UUID.randomUUID();
+        final UUID objectId = UUID.randomUUID();
         final ObjectType objectType = ObjectType.INVOICE;
         final String name = UUID.randomUUID().toString();
         final String value = UUID.randomUUID().toString();
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java
index 5bc6273..093e5ca 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestEntitlementJsonWithEvents.java
@@ -43,15 +43,15 @@ public class TestEntitlementJsonWithEvents extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String accountId = UUID.randomUUID().toString();
-        final String bundleId = UUID.randomUUID().toString();
-        final String subscriptionId = UUID.randomUUID().toString();
+        final UUID accountId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
+        final UUID subscriptionId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
         final DateTime effectiveDate = DefaultClock.toUTCDateTime(new DateTime(DateTimeZone.UTC));
         final UUID eventId = UUID.randomUUID();
         final List<AuditLogJson> auditLogs = createAuditLogsJson(clock.getUTCNow());
 
-        final EventSubscriptionJson newEvent = new EventSubscriptionJson(eventId.toString(),
+        final EventSubscriptionJson newEvent = new EventSubscriptionJson(eventId,
                                                                          BillingPeriod.NO_BILLING_PERIOD.toString(),
                                                                          effectiveDate.toLocalDate(),
                                                                          UUID.randomUUID().toString(),
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceEmailJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceEmailJson.java
index 32a4378..f3a5a34 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceEmailJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceEmailJson.java
@@ -28,7 +28,7 @@ public class TestInvoiceEmailJson extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String accountId = UUIDs.randomUUID().toString();
+        final UUID accountId = UUIDs.randomUUID();
         final boolean isNotifiedForInvoices = true;
 
         final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountId, isNotifiedForInvoices);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
index f61257d..833b874 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
@@ -35,13 +35,13 @@ public class TestInvoiceItemJsonSimple extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String invoiceItemId = UUID.randomUUID().toString();
-        final String invoiceId = UUID.randomUUID().toString();
-        final String linkedInvoiceItemId = UUID.randomUUID().toString();
-        final String accountId = UUID.randomUUID().toString();
-        final String childAccountId = UUID.randomUUID().toString();
-        final String bundleId = UUID.randomUUID().toString();
-        final String subscriptionId = UUID.randomUUID().toString();
+        final UUID invoiceItemId = UUID.randomUUID();
+        final UUID invoiceId = UUID.randomUUID();
+        final UUID linkedInvoiceItemId = UUID.randomUUID();
+        final UUID accountId = UUID.randomUUID();
+        final UUID childAccountId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
+        final UUID subscriptionId = UUID.randomUUID();
         final String planName = UUID.randomUUID().toString();
         final String phaseName = UUID.randomUUID().toString();
         final String usageName = UUID.randomUUID().toString();
@@ -100,12 +100,12 @@ public class TestInvoiceItemJsonSimple extends JaxrsTestSuiteNoDB {
         Mockito.when(invoiceItem.getInvoiceItemType()).thenReturn(InvoiceItemType.FIXED);
 
         final InvoiceItemJson invoiceItemJson = new InvoiceItemJson(invoiceItem);
-        Assert.assertEquals(invoiceItemJson.getInvoiceItemId(), invoiceItem.getId().toString());
-        Assert.assertEquals(invoiceItemJson.getInvoiceId(), invoiceItem.getInvoiceId().toString());
-        Assert.assertEquals(invoiceItemJson.getLinkedInvoiceItemId(), invoiceItem.getLinkedItemId().toString());
-        Assert.assertEquals(invoiceItemJson.getAccountId(), invoiceItem.getAccountId().toString());
-        Assert.assertEquals(invoiceItemJson.getBundleId(), invoiceItem.getBundleId().toString());
-        Assert.assertEquals(invoiceItemJson.getSubscriptionId(), invoiceItem.getSubscriptionId().toString());
+        Assert.assertEquals(invoiceItemJson.getInvoiceItemId(), invoiceItem.getId());
+        Assert.assertEquals(invoiceItemJson.getInvoiceId(), invoiceItem.getInvoiceId());
+        Assert.assertEquals(invoiceItemJson.getLinkedInvoiceItemId(), invoiceItem.getLinkedItemId());
+        Assert.assertEquals(invoiceItemJson.getAccountId(), invoiceItem.getAccountId());
+        Assert.assertEquals(invoiceItemJson.getBundleId(), invoiceItem.getBundleId());
+        Assert.assertEquals(invoiceItemJson.getSubscriptionId(), invoiceItem.getSubscriptionId());
         Assert.assertEquals(invoiceItemJson.getPlanName(), invoiceItem.getPlanName());
         Assert.assertEquals(invoiceItemJson.getPhaseName(), invoiceItem.getPhaseName());
         Assert.assertEquals(invoiceItemJson.getUsageName(), invoiceItem.getUsageName());
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
index 5dc7791..5dcbc4e 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
@@ -41,12 +41,12 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuiteNoDB {
         final BigDecimal amount = BigDecimal.TEN;
         final BigDecimal creditAdj = BigDecimal.ONE;
         final BigDecimal refundAdj = BigDecimal.ONE;
-        final String invoiceId = UUID.randomUUID().toString();
+        final UUID invoiceId = UUID.randomUUID();
         final LocalDate invoiceDate = clock.getUTCToday();
         final LocalDate targetDate = clock.getUTCToday();
         final String invoiceNumber = UUID.randomUUID().toString();
         final BigDecimal balance = BigDecimal.ZERO;
-        final String accountId = UUID.randomUUID().toString();
+        final UUID accountId = UUID.randomUUID();
         final String bundleKeys = UUID.randomUUID().toString();
         final CreditJson creditJson = createCreditJson();
         final List<CreditJson> credits = ImmutableList.<CreditJson>of(creditJson);
@@ -98,12 +98,12 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuiteNoDB {
         Assert.assertEquals(invoiceJson.getAmount(), invoice.getChargedAmount());
         Assert.assertEquals(invoiceJson.getCreditAdj(), invoice.getCreditedAmount());
         Assert.assertEquals(invoiceJson.getRefundAdj(), invoice.getRefundedAmount());
-        Assert.assertEquals(invoiceJson.getInvoiceId(), invoice.getId().toString());
+        Assert.assertEquals(invoiceJson.getInvoiceId(), invoice.getId());
         Assert.assertEquals(invoiceJson.getInvoiceDate(), invoice.getInvoiceDate());
         Assert.assertEquals(invoiceJson.getTargetDate(), invoice.getTargetDate());
         Assert.assertEquals(invoiceJson.getInvoiceNumber(), String.valueOf(invoice.getInvoiceNumber()));
         Assert.assertEquals(invoiceJson.getBalance(), invoice.getBalance());
-        Assert.assertEquals(invoiceJson.getAccountId(), invoice.getAccountId().toString());
+        Assert.assertEquals(invoiceJson.getAccountId(), invoice.getAccountId());
         Assert.assertEquals(invoiceJson.getBundleKeys(), bundleKeys);
         Assert.assertEquals(invoiceJson.getCredits(), credits);
         Assert.assertNull(invoiceJson.getAuditLogs());
@@ -113,10 +113,10 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuiteNoDB {
     private CreditJson createCreditJson() {
         final BigDecimal creditAmount = BigDecimal.TEN;
         final Currency currency = Currency.USD;
-        final String invoiceId = UUID.randomUUID().toString();
+        final UUID invoiceId = UUID.randomUUID();
         final String invoiceNumber = UUID.randomUUID().toString();
         final LocalDate effectiveDate = clock.getUTCToday();
-        final String accountId = UUID.randomUUID().toString();
+        final UUID accountId = UUID.randomUUID();
         return new CreditJson(creditAmount, currency.name(), invoiceId, invoiceNumber, effectiveDate,  accountId, null, null);
     }
 }
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestSubscriptionUsageRecordJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestSubscriptionUsageRecordJson.java
index 95c232b..7af09df 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestSubscriptionUsageRecordJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestSubscriptionUsageRecordJson.java
@@ -34,7 +34,7 @@ public class TestSubscriptionUsageRecordJson extends JaxrsTestSuiteNoDB {
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final LocalDate localDate = new LocalDate();
-        final String subscriptionId = UUID.randomUUID().toString();
+        final UUID subscriptionId = UUID.randomUUID();
         final String trackingId = UUID.randomUUID().toString();
         final List<UnitUsageRecordJson> unitUsageRecords = new ArrayList<UnitUsageRecordJson>();
         final List<UsageRecordJson> usageRecords = new ArrayList<UsageRecordJson>();
@@ -53,7 +53,7 @@ public class TestSubscriptionUsageRecordJson extends JaxrsTestSuiteNoDB {
         Assert.assertEquals(subscriptionUsageRecordJson.getUnitUsageRecords().get(0).getUsageRecords().get(0).getRecordDate(), localDate);
 
         final SubscriptionUsageRecord subscriptionUsageRecord = subscriptionUsageRecordJson.toSubscriptionUsageRecord();
-        Assert.assertEquals(subscriptionUsageRecord.getSubscriptionId().toString(), subscriptionId);
+        Assert.assertEquals(subscriptionUsageRecord.getSubscriptionId(), subscriptionId);
         Assert.assertEquals(subscriptionUsageRecord.getTrackingId(), trackingId);
         Assert.assertEquals(subscriptionUsageRecord.getUnitUsageRecord().size(), 1);
         Assert.assertEquals(subscriptionUsageRecord.getUnitUsageRecord().get(0).getUnitType(), "foo");
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestTagDefinitionJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestTagDefinitionJson.java
index 2a6da5e..be48168 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestTagDefinitionJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestTagDefinitionJson.java
@@ -30,7 +30,7 @@ public class TestTagDefinitionJson extends JaxrsTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
-        final String id = UUID.randomUUID().toString();
+        final UUID id = UUID.randomUUID();
         final Boolean isControlTag = true;
         final String name = UUID.randomUUID().toString();
         final String description = UUID.randomUUID().toString();
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
index 8217696..252d079 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
@@ -236,7 +236,7 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
 
     private int calculateBcdForTransition(final Catalog catalog, final Map<UUID, Integer> bcdCache, final SubscriptionBase baseSubscription, final SubscriptionBase subscription, final int accountBillCycleDayLocal, final EffectiveSubscriptionInternalEvent transition, final InternalTenantContext internalTenantContext)
             throws CatalogApiException, AccountApiException, SubscriptionBaseApiException {
-        final BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), transition.getEffectiveTransitionTime());
+        final BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), subscription.getStartDate());
         return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, internalTenantContext, accountBillCycleDayLocal);
     }
 

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 525ead6..c1933c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.141.41-SNAPSHOT</version>
+        <version>0.141.43</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.19.6-SNAPSHOT</version>
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java
index d393cb8..813f705 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java
@@ -28,6 +28,7 @@ import javax.servlet.ServletContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import ch.qos.logback.classic.LoggerContext;
 import net.sf.log4jdbc.sql.jdbcapi.DriverSpy;
 
 public class CleanupListener implements ServletContextListener {
@@ -76,5 +77,9 @@ public class CleanupListener implements ServletContextListener {
                 logger.warn("Unable to de-register driver", e);
             }
         }
+
+//         avoid memory leaks: https://logback.qos.ch/manual/jmxConfig.html
+        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+        lc.stop();
     }
 }
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
index b9cb18c..abb1544 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
@@ -160,9 +160,9 @@ public class PushNotificationListener {
     public void resendPushNotification(final PushNotificationKey key) throws JsonProcessingException {
 
         final NotificationJson notification = new NotificationJson(key.getEventType() != null ? key.getEventType().toString() : null,
-                                                                   key.getAccountId() != null ? key.getAccountId().toString() : null,
+                                                                   key.getAccountId(),
                                                                    key.getObjectType() != null ? key.getObjectType().toString() : null,
-                                                                   key.getObjectId() != null ? key.getObjectId().toString() : null,
+                                                                   key.getObjectId(),
                                                                    key.getMetaData());
         final String body = mapper.writeValueAsString(notification);
         doPost(key.getTenantId(), key.getUrl(), body, notification, TIMEOUT_NOTIFICATION, key.getAttemptNumber());
@@ -170,10 +170,10 @@ public class PushNotificationListener {
 
     private void saveRetryPushNotificationInQueue(final UUID tenantId, final String url, final NotificationJson notificationJson, final int attemptRetryNumber) {
         final PushNotificationKey key = new PushNotificationKey(tenantId,
-                                                                notificationJson.getAccountId() != null ? UUID.fromString(notificationJson.getAccountId()) : null,
+                                                                notificationJson.getAccountId(),
                                                                 notificationJson.getEventType(),
                                                                 notificationJson.getObjectType(),
-                                                                notificationJson.getObjectId() != null ? UUID.fromString(notificationJson.getObjectId()) : null,
+                                                                notificationJson.getObjectId(),
                                                                 attemptRetryNumber + 1,
                                                                 notificationJson.getMetaData(),
                                                                 url);
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java b/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java
index 7b460c0..50b1138 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java
@@ -37,6 +37,7 @@ import org.apache.shiro.authc.UsernamePasswordToken;
 import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
 import org.apache.shiro.realm.Realm;
 import org.killbill.billing.jaxrs.resources.JaxrsResource;
+import org.killbill.billing.jaxrs.resources.KillBillApiDefinition;
 import org.killbill.billing.jaxrs.util.Context;
 import org.killbill.billing.server.listeners.KillbillGuiceListener;
 import org.killbill.billing.tenant.api.Tenant;
@@ -128,66 +129,23 @@ public class TenantFilter implements Filter {
 
     private boolean shouldContinueIfTenantInformationIsWrongOrMissing(final ServletRequest request) {
         boolean shouldContinue = false;
-
         if (request instanceof HttpServletRequest) {
             final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
             final String path = httpServletRequest.getPathInfo();
             final String httpMethod = httpServletRequest.getMethod();
-            if (    // Chicken - egg problem
-                    isTenantCreationRequest(path, httpMethod) ||
-                    // Retrieve user permissions should not require tenant info since this is cross tenants
-                    isPermissionRequest(path) ||
-                    // Node request are cross tenant
-                    isNodeInfoRequest(path) ||
-                    // Metrics servlets
-                    isMetricsRequest(path, httpMethod) ||
-                    // See KillBillShiroWebModule#CorsBasicHttpAuthenticationFilter
-                    isOptionsRequest(httpMethod) ||
-                    // Shift the responsibility to the plugin
-                    isPluginRequest(path) ||
-                    // Static resources (welcome screen, Swagger, etc.)
-                    isNotKbNorPluginResourceRequest(path, httpMethod)
-                    ) {
-                shouldContinue = true;
-            }
+            shouldContinue = shouldContinueIfTenantInformationIsWrongOrMissing(path, httpMethod);
         }
-
         return shouldContinue;
     }
 
-
-
-    private boolean isPermissionRequest(final String path) {
-        return path != null && path.startsWith(JaxrsResource.SECURITY_PATH);
-    }
-
-    private boolean isTenantCreationRequest(final String path, final String httpMethod) {
-        return JaxrsResource.TENANTS_PATH.equals(path) && "POST".equals(httpMethod);
-    }
-
-    private boolean isNodeInfoRequest(final String path) {
-        return JaxrsResource.NODES_INFO_PATH.equals(path);
+    private static boolean isMetricsRequest(final String path, final String httpMethod) {
+        return KillbillGuiceListener.METRICS_SERVLETS_PATHS.contains(path) && "GET".equalsIgnoreCase(httpMethod);
     }
 
-    private boolean isMetricsRequest(final String path, final String httpMethod) {
-        return KillbillGuiceListener.METRICS_SERVLETS_PATHS.contains(path) && "GET".equals(httpMethod);
-    }
-
-    private boolean isOptionsRequest(final String httpMethod) {
-        return "OPTIONS".equals(httpMethod);
-    }
-
-
-    private boolean isNotKbNorPluginResourceRequest(final String path, final String httpMethod) {
-        return !isPluginRequest(path) && !isKbApiRequest(path) && "GET".equals(httpMethod);
-    }
-
-    private boolean isKbApiRequest(final String path) {
-        return path != null && path.startsWith(JaxrsResource.PREFIX);
-    }
 
-    private boolean isPluginRequest(final String path) {
-        return path != null && path.startsWith(JaxrsResource.PLUGINS_PATH);
+    public static boolean shouldContinueIfTenantInformationIsWrongOrMissing(final String path, final String httpMethod) {
+        final boolean requiresTenantInfo = KillBillApiDefinition.requiresTenantInformation(path, httpMethod);
+        return isMetricsRequest(path, httpMethod) || !requiresTenantInfo;
     }
 
     private void sendAuthError(final ServletResponse response, final String errorMessage) throws IOException {
diff --git a/profiles/killbill/src/main/resources/logback.xml b/profiles/killbill/src/main/resources/logback.xml
index c2c710a..1d267cb 100644
--- a/profiles/killbill/src/main/resources/logback.xml
+++ b/profiles/killbill/src/main/resources/logback.xml
@@ -17,12 +17,13 @@
   -->
 
 <configuration>
+    <jmxConfigurator />
     <conversionRule conversionWord="maskedMsg" converterClass="org.killbill.billing.server.log.obfuscators.ObfuscatorConverter" />
 
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
         <encoder>
             <!-- See http://jira.qos.ch/browse/LOGBACK-262 -->
-            <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
+            <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', tok='%X{kb.userToken}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
         </encoder>
     </appender>
 
@@ -43,7 +44,7 @@
                     </timeBasedFileNamingAndTriggeringPolicy>
                 </rollingPolicy>
                 <encoder>
-                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
+                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', tok='%X{kb.userToken}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
                 </encoder>
             </appender>
         </sift>
@@ -64,7 +65,7 @@
                     </timeBasedFileNamingAndTriggeringPolicy>
                 </rollingPolicy>
                 <encoder>
-                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
+                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', tok='%X{kb.userToken}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
                 </encoder>
             </appender>
         </sift>
@@ -85,7 +86,7 @@
                     </timeBasedFileNamingAndTriggeringPolicy>
                 </rollingPolicy>
                 <encoder>
-                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
+                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', tok='%X{kb.userToken}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
                 </encoder>
             </appender>
         </sift>
@@ -106,7 +107,7 @@
                     </timeBasedFileNamingAndTriggeringPolicy>
                 </rollingPolicy>
                 <encoder>
-                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
+                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', tok='%X{kb.userToken}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
                 </encoder>
             </appender>
         </sift>
@@ -127,7 +128,7 @@
                     </timeBasedFileNamingAndTriggeringPolicy>
                 </rollingPolicy>
                 <encoder>
-                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
+                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', tok='%X{kb.userToken}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
                 </encoder>
             </appender>
         </sift>
@@ -148,7 +149,7 @@
                     </timeBasedFileNamingAndTriggeringPolicy>
                 </rollingPolicy>
                 <encoder>
-                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
+                    <pattern>%date{"yyyy-MM-dd'T'HH:mm:ss,SSSZ", UTC} lvl='%level', log='%logger{0}', th='%thread', xff='%X{req.xForwardedFor}', rId='%X{req.requestId}', tok='%X{kb.userToken}', aRId='%X{kb.accountRecordId}', tRId='%X{kb.tenantRecordId}', %maskedMsg%n</pattern>
                 </encoder>
             </appender>
         </sift>
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPushNotification.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPushNotification.java
index 17cae7a..5d08db5 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPushNotification.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPushNotification.java
@@ -112,10 +112,10 @@ public class TestPushNotification extends TestJaxrsBase {
         return (remainingMs > 0);
     }
 
-    public void retrieveAccountWithAsserts(final String accountId) {
+    public void retrieveAccountWithAsserts(final UUID accountId) {
         try {
             // Just check we can retrieve the account with the id from the callback
-            killBillClient.getAccount(UUID.fromString(accountId), requestOptions);
+            killBillClient.getAccount(accountId, requestOptions);
         } catch (final Exception e) {
             Assert.fail(e.getMessage());
         }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index fab57eb..20616d9 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -737,7 +737,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
                             final Plan currentPlan = subscriptionForCancellation.getCurrentPlan();
                             final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(),
                                                                                    subscriptionForCancellation.getCurrentPhase().getPhaseType());
-                            policy = catalog.planCancelPolicy(spec, utcNow);
+                            policy = catalog.planCancelPolicy(spec, subscriptionForCancellation.getStartDate());
                         }
                         // We pass null for billingAlignment, accountTimezone, account BCD because this is not available which means that dryRun with START_OF_TERM BillingPolicy will fail
                         cancelEffectiveDate = subscriptionForCancellation.getPlanChangeEffectiveDate(policy, null, -1, context);
@@ -791,7 +791,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
 
         try {
             final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
-            final BillingAlignment alignment = catalog.billingAlignment(planPhaseSpecifier, effectiveDate);
+            final BillingAlignment alignment = catalog.billingAlignment(planPhaseSpecifier, subscription.getStartDate());
             return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, context, accountBillCycleDayLocal);
         } catch (final CatalogApiException e) {
             throw new SubscriptionBaseApiException(e);
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
index 07a5515..7437681 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
@@ -185,7 +185,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
         try {
             final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
             final Catalog fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext);
-            final BillingActionPolicy policy = fullCatalog.planCancelPolicy(planPhase, now);
+            final BillingActionPolicy policy = fullCatalog.planCancelPolicy(planPhase, subscription.getStartDate());
 
             Preconditions.checkState(policy != BillingActionPolicy.START_OF_TERM, "A default START_OF_TERM policy is not availaible");
 
@@ -239,7 +239,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
 
         try {
             for (final DefaultSubscriptionBase subscription : subscriptions) {
-                final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()), clock.getUTCNow()));
+                final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()), subscription.getStartDate()));
                 final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, billingAlignment, accountBillCycleDayLocal, context);
                 subscriptionsWithEffectiveDate.put(subscription, effectiveDate);
             }
@@ -404,7 +404,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
 
             final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getName(),
                                                                             subscription.getCurrentOrPendingPhase().getPhaseType());
-            planChangeResult = catalogInternalApi.getFullCatalog(true, true, internalCallContext).planChange(fromPlanPhase, toPlanPhase, effectiveDate);
+            planChangeResult = catalogInternalApi.getFullCatalog(true, true, internalCallContext).planChange(fromPlanPhase, toPlanPhase, subscription.getStartDate());
         } catch (final CatalogApiException e) {
             throw new SubscriptionBaseApiException(e);
         }
diff --git a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
index 9a8abae..41158ff 100644
--- a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
+++ b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
@@ -51,6 +51,7 @@ public class InternalCallContextFactory {
 
     public static final String MDC_KB_ACCOUNT_RECORD_ID = "kb.accountRecordId";
     public static final String MDC_KB_TENANT_RECORD_ID = "kb.tenantRecordId";
+    public static final String MDC_KB_USER_TOKEN = "kb.userToken";
 
     private final ImmutableAccountInternalApi accountInternalApi;
     private final Clock clock;
@@ -159,7 +160,7 @@ public class InternalCallContextFactory {
          * @return internal tenant callcontext
          */
     public InternalTenantContext createInternalTenantContext(final Long tenantRecordId, @Nullable final Long accountRecordId) {
-        populateMDCContext(accountRecordId, tenantRecordId);
+        populateMDCContext(null, accountRecordId, tenantRecordId);
 
         if (accountRecordId == null) {
             return new InternalTenantContext(tenantRecordId);
@@ -245,7 +246,7 @@ public class InternalCallContextFactory {
     public InternalCallContext createInternalCallContextWithoutAccountRecordId(final CallContext context) {
         // If tenant id is null, this will default to the default tenant record id (multi-tenancy disabled)
         final Long tenantRecordId = getTenantRecordIdSafe(context);
-        populateMDCContext(null, tenantRecordId);
+        populateMDCContext(context.getUserToken(), null, tenantRecordId);
         return new InternalCallContext(tenantRecordId, context, clock.getUTCNow());
     }
 
@@ -254,7 +255,7 @@ public class InternalCallContextFactory {
         final ImmutableAccountData immutableAccountData = getImmutableAccountData(accountRecordId, context.getTenantRecordId());
         final DateTimeZone fixedOffsetTimeZone = immutableAccountData.getFixedOffsetTimeZone();
         final DateTime referenceTime = immutableAccountData.getReferenceTime();
-        populateMDCContext(accountRecordId, context.getTenantRecordId());
+        populateMDCContext(context.getUserToken(), accountRecordId, context.getTenantRecordId());
         return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, clock.getUTCNow());
     }
 
@@ -263,12 +264,12 @@ public class InternalCallContextFactory {
         // See DefaultImmutableAccountData implementation
         final DateTimeZone fixedOffsetTimeZone = AccountDateTimeUtils.getFixedOffsetTimeZone(accountModelDao);
         final DateTime referenceTime = accountModelDao.getReferenceTime();
-        populateMDCContext(accountRecordId, context.getTenantRecordId());
+        populateMDCContext(context.getUserToken(), accountRecordId, context.getTenantRecordId());
         return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, clock.getUTCNow());
     }
 
     public InternalCallContext createInternalCallContext(final DateTimeZone fixedOffsetTimeZone, final DateTime referenceTime, final Long accountRecordId, final InternalCallContext context) {
-        populateMDCContext(accountRecordId, context.getTenantRecordId());
+        populateMDCContext(context.getUserToken(), accountRecordId, context.getTenantRecordId());
         return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, clock.getUTCNow());
     }
 
@@ -299,7 +300,7 @@ public class InternalCallContextFactory {
             referenceTime = immutableAccountData.getReferenceTime();
         }
 
-        populateMDCContext(accountRecordId, nonNulTenantRecordId);
+        populateMDCContext(userToken, accountRecordId, nonNulTenantRecordId);
 
         return new InternalCallContext(nonNulTenantRecordId,
                                        accountRecordId,
@@ -327,11 +328,12 @@ public class InternalCallContextFactory {
         }
     }
 
-    private void populateMDCContext(@Nullable final Long accountRecordId, final Long tenantRecordId) {
+    private void populateMDCContext(@Nullable final UUID userToken, @Nullable final Long accountRecordId, final Long tenantRecordId) {
         if (accountRecordId != null) {
             MDC.put(MDC_KB_ACCOUNT_RECORD_ID, String.valueOf(accountRecordId));
         }
         MDC.put(MDC_KB_TENANT_RECORD_ID, String.valueOf(tenantRecordId));
+        MDC.put(MDC_KB_USER_TOKEN, userToken != null ? userToken.toString() : null);
     }
 
     //