+
+> Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
+
+API description for OpenHouse Tables API
+
+Base URLs:
+
+* http://localhost:8080
+
+Terms of service
+
+License: Apache 2.0
+
+
+
+## Get Table in a Database
+
+
+
+> Code samples
+
+`GET /v1/databases/{databaseId}/tables/{tableId}`
+
+Returns a Table resource identified by tableId in the database identified by databaseId.
+
+
+
+## Get AclPolicies on Database
+
+
+
+> Code samples
+
+`GET /databases/{databaseId}/aclPolicies`
+
+Returns principal to role mappings on resource identified by databaseId.
+
+
+
+
+
+
+
+
+```json
+"\"clustering\":[{\"columnName\":\"country\"},{\"columnName\":\"city\"}]"
+
+```
+
+Clustering columns for the table
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|columnName|string|true|none|Name of the clustering column in provided schema. The column should be of the type 'String'.Nested columns can also be provided with a dot-separated name (for example: 'eventHeader.countryCode').Column name is case-sensitive.|
+
+
CreateUpdateTableRequestBody
+
+
+
+
+
+
+```json
+{
+ "tableId": "my_table",
+ "databaseId": "my_database",
+ "clusterId": "my_cluster",
+ "schema": "{\"type\":\"struct\",\"fields\":[{\"id\":1,\"required\":true,\"name\":\"id\",\"type\":\"string\"},{\"id\":2,\"required\":true,\"name\":\"name\",\"type\":\"string\"},{\"id\":3,\"required\":true,\"name\":\"timestampColumn\",\"type\":\"timestamp\"}]}",
+ "timePartitioning": "\"timePartitioning\":{\"columnName\":\"timestampCol\",\"granularity\":\"HOUR\"}",
+ "clustering": "\"clustering\":[{\"columnName\":\"country\"},{\"columnName\":\"city\"}]",
+ "tableProperties": {
+ "key": "value"
+ },
+ "policies": {
+ "retention": "{retention:{count:3, granularity: 'day'}}",
+ "sharingEnabled": false,
+ "columnTags": "{'colName': [PII, HC]}"
+ },
+ "stageCreate": false,
+ "baseTableVersion": "string",
+ "tableType": "PRIMARY_TABLE"
+}
+
+```
+
+Request containing details of the Table to be created
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|tableId|string|true|none|Unique Resource identifier for a table within a Database|
+|databaseId|string|true|none|Unique Resource identifier for the Database containing the Table|
+|clusterId|string|true|none|Unique Resource identifier for the Cluster containing the Database|
+|schema|string|true|none|Schema of the table. OpenHouse tables use Iceberg schema specification|
+|timePartitioning|[TimePartitionSpec](#schematimepartitionspec)|false|none|Time partitioning of the table|
+|clustering|[[ClusteringColumn](#schemaclusteringcolumn)]¦null|false|none|Clustering columns for the table|
+|tableProperties|object|true|none|Table properties|
+|» **additionalProperties**|string|false|none|Table properties|
+|policies|[Policies](#schemapolicies)|false|none|Policies of the table|
+|stageCreate|boolean|false|none|Boolean that determines creating a staged table|
+|baseTableVersion|string|true|none|The version of table that the current update is based upon|
+|tableType|string|false|none|The type of a table|
+
+#### Enumerated Values
+
+|Property|Value|
+|---|---|
+|tableType|PRIMARY_TABLE|
+|tableType|REPLICA_TABLE|
+
+
IcebergSnapshotsRequestBody
+
+
+
+
+
+
+```json
+{
+ "baseTableVersion": "Base table version to apply the change to",
+ "jsonSnapshots": [
+ "string"
+ ],
+ "createUpdateTableRequestBody": {
+ "tableId": "my_table",
+ "databaseId": "my_database",
+ "clusterId": "my_cluster",
+ "schema": "{\"type\":\"struct\",\"fields\":[{\"id\":1,\"required\":true,\"name\":\"id\",\"type\":\"string\"},{\"id\":2,\"required\":true,\"name\":\"name\",\"type\":\"string\"},{\"id\":3,\"required\":true,\"name\":\"timestampColumn\",\"type\":\"timestamp\"}]}",
+ "timePartitioning": "\"timePartitioning\":{\"columnName\":\"timestampCol\",\"granularity\":\"HOUR\"}",
+ "clustering": "\"clustering\":[{\"columnName\":\"country\"},{\"columnName\":\"city\"}]",
+ "tableProperties": {
+ "key": "value"
+ },
+ "policies": {
+ "retention": "{retention:{count:3, granularity: 'day'}}",
+ "sharingEnabled": false,
+ "columnTags": "{'colName': [PII, HC]}"
+ },
+ "stageCreate": false,
+ "baseTableVersion": "string",
+ "tableType": "PRIMARY_TABLE"
+ }
+}
+
+```
+
+Request containing a list of JSON serialized Iceberg Snapshots to be put
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|baseTableVersion|string|true|none|Base Table Version|
+|jsonSnapshots|[string]|false|none|List of json serialized snapshots to put|
+|createUpdateTableRequestBody|[CreateUpdateTableRequestBody](#schemacreateupdatetablerequestbody)|false|none|Request containing details of the Table to be created|
+
+
Policies
+
+
+
+
+
+
+```json
+{
+ "retention": "{retention:{count:3, granularity: 'day'}}",
+ "sharingEnabled": false,
+ "columnTags": "{'colName': [PII, HC]}"
+}
+
+```
+
+Policies of the table
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|retention|[Retention](#schemaretention)|false|none|Retention as required in /tables API request. The column holds the retention part or Policies.|
+|sharingEnabled|boolean|false|none|Whether data sharing needs to enabled for the table in /tables API request. Sharing is disabled by default|
+|columnTags|object|false|none|Policy tags applied to columns in /tables API request.|
+|» **additionalProperties**|[PolicyTag](#schemapolicytag)|false|none|Policy tags applied to columns in /tables API request.|
+
+
+
+
+
+
+
+
+```json
+"{retention:{count:3, granularity: 'day'}}"
+
+```
+
+Retention as required in /tables API request. The column holds the retention part or Policies.
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|count|integer(int32)|true|none|time period in count for which the retention on table will be applied|
+|granularity|string|true|none|time period granularity for which the retention on table will be applied|
+|columnPattern|[RetentionColumnPattern](#schemaretentioncolumnpattern)|false|none|Optional object to specify retention column in case where timestamp is represented as a string|
+
+#### Enumerated Values
+
+|Property|Value|
+|---|---|
+|granularity|HOUR|
+|granularity|DAY|
+|granularity|MONTH|
+|granularity|YEAR|
+
+
RetentionColumnPattern
+
+
+
+
+
+
+```json
+"{columnName:datepartition, pattern: yyyy-MM-dd-HH}"
+
+```
+
+Optional object to specify retention column in case where timestamp is represented as a string
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|columnName|string|true|none|Name of retention column|
+|pattern|string|true|none|Pattern for the value of the retention column following java.time.format.DateTimeFormatter standard.|
+
+
TimePartitionSpec
+
+
+
+
+
+
+```json
+"\"timePartitioning\":{\"columnName\":\"timestampCol\",\"granularity\":\"HOUR\"}"
+
+```
+
+Time partitioning of the table
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|columnName|string|true|none|Name of the timestamp column in provided schema. The column should be of the type 'Timestamp'. Nested columns can also be provided with a dot-separated name (for example: 'eventHeader.timeColumn').Column name is case-sensitive.|
+|granularity|string|true|none|Granularity of the time partition.|
+
+#### Enumerated Values
+
+|Property|Value|
+|---|---|
+|granularity|HOUR|
+|granularity|DAY|
+|granularity|MONTH|
+|granularity|YEAR|
+
+
GetTableResponseBody
+
+
+
+
+
+
+```json
+{
+ "tableId": "my_table",
+ "databaseId": "my_database",
+ "clusterId": "my_cluster",
+ "tableUri": "my_cluster.my_database.my_table",
+ "tableUUID": "73ea0d21-3c89-4987-a6cf-26e4f86bdcee",
+ "tableLocation": "://////metadata/.metadata.json",
+ "tableVersion": "string",
+ "tableCreator": "bob",
+ "schema": "{\"type\":\"struct\",\"fields\":[{\"id\":1,\"required\":true,\"name\":\"id\",\"type\":\"string\"},{\"id\":2,\"required\":true,\"name\":\"name\",\"type\":\"string\"}]}",
+ "lastModifiedTime": 1651002318265,
+ "creationTime": 1651002318265,
+ "tableProperties": {
+ "key": "value"
+ },
+ "timePartitioning": "\"timePartitioning\":{\"columnName\":\"timestampCol\",\"granularity\":\"HOUR\"}",
+ "clustering": [
+ "\"clustering\":[{\"columnName\":\"country\"},{\"columnName\":\"city\"}]"
+ ],
+ "policies": {
+ "retention": "{retention:{count:3, granularity: 'day'}}",
+ "sharingEnabled": false,
+ "columnTags": "{'colName': [PII, HC]}"
+ },
+ "tableType": "PRIMARY_TABLE"
+}
+
+```
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|tableId|string|false|read-only|Unique Resource identifier for a table within a Database|
+|databaseId|string|false|read-only|Unique Resource identifier for the Database containing the Table|
+|clusterId|string|false|read-only|Unique Resource identifier for the Cluster containing the Database|
+|tableUri|string|false|read-only|Fully Qualified Resource URI for the table|
+|tableUUID|string|false|read-only|Table UUID|
+|tableLocation|string|false|read-only|Location of Table in File System / Blob Store|
+|tableVersion|string|false|read-only|Current Version of the Table.|
+|tableCreator|string|false|read-only|Authenticated user principal that created the Table.|
+|schema|string|false|read-only|Schema of the Table in Iceberg|
+|lastModifiedTime|integer(int64)|false|read-only|Last modification epoch time in UTC measured in milliseconds of a table.|
+|creationTime|integer(int64)|false|read-only|Table creation epoch time measured in UTC in milliseconds of a table.|
+|tableProperties|object|false|read-only|A map of table properties|
+|» **additionalProperties**|string|false|none|A map of table properties|
+|timePartitioning|[TimePartitionSpec](#schematimepartitionspec)|false|none|Time partitioning of the table|
+|clustering|[[ClusteringColumn](#schemaclusteringcolumn)]¦null|false|none|Clustering columns for the table|
+|policies|[Policies](#schemapolicies)|false|none|Policies of the table|
+|tableType|string|false|read-only|The type of a table|
+
+#### Enumerated Values
+
+|Property|Value|
+|---|---|
+|tableType|PRIMARY_TABLE|
+|tableType|REPLICA_TABLE|
+
+
+
+
+
+
+
+
+```json
+{
+ "role": "string",
+ "principal": "string",
+ "operation": "GRANT"
+}
+
+```
+
+Request containing aclPolicies of the Database to be updated
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|role|string|true|none|Role that is being granted/revoked.|
+|principal|string|true|none|Grantee principal whose role is being updated|
+|operation|string|true|none|Whether this is a grant/revoke request|
+
+#### Enumerated Values
+
+|Property|Value|
+|---|---|
+|operation|GRANT|
+|operation|REVOKE|
+
+
AclPolicy
+
+
+
+
+
+
+```json
+{
+ "principal": "string",
+ "role": "string"
+}
+
+```
+
+List of acl policies associated with table/database
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|principal|string|false|read-only|Principal with the role on the table/database|
+|role|string|false|read-only|Role associated with the principal|
+
+
+
+
+
+
+
+
+```json
+{
+ "databaseId": "my_database",
+ "clusterId": "my_cluster"
+}
+
+```
+
+List of Database objects
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|databaseId|string|false|read-only|Unique Resource identifier for the Database|
+|clusterId|string|false|read-only|Unique Resource identifier for the Cluster containing the Database|
+
diff --git a/specs/housetables.md b/specs/housetables.md
new file mode 100644
index 00000000..8f954b77
--- /dev/null
+++ b/specs/housetables.md
@@ -0,0 +1,652 @@
+
+
+
House Tables API v0.0.1
+
+> Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
+
+API description for House Tables API
+
+Base URLs:
+
+* http://localhost:8080
+
+Terms of service
+
+License: Apache 2.0
+
+
UserTable
+
+## Get User Table identified by databaseID and tableId.
+
+
+
+> Code samples
+
+`GET /hts/tables`
+
+Returns a User House Table identified by databaseID and tableId.
+
+
+
+|Status|Meaning|Description|Schema|
+|---|---|---|---|
+|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|User Table GET: OK|[EntityResponseBodyUserTable](#schemaentityresponsebodyusertable)|
+|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|User Table GET: TBL_DB_NOT_FOUND|[EntityResponseBodyUserTable](#schemaentityresponsebodyusertable)|
+
+
+
+## Update a User Table
+
+
+
+> Code samples
+
+`PUT /hts/tables`
+
+Updates or creates a User House Table identified by databaseID and tableId. If the table does not exist, it will be created. If the table exists, it will be updated.
+
+> Body parameter
+
+```json
+{
+ "entity": {
+ "tableId": "my_table",
+ "databaseId": "my_database",
+ "tableVersion": "string",
+ "metadataLocation": "string"
+ }
+}
+```
+
+
+
+|Status|Meaning|Description|Schema|
+|---|---|---|---|
+|204|[No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5)|User Table DELETE: NO_CONTENT|None|
+|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|User Table DELETE: BAD_REQUEST|None|
+|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|User Table DELETE: TBL_DB_NOT_FOUND|None|
+
+
+
+## Search User Table by filter.
+
+
+
+> Code samples
+
+`GET /hts/tables/query`
+
+Returns user table from house table that fulfills the predicate. For examples, one could provide {databaseId: d1} in the map to query all tables from database d1.
+
+
+
+|Status|Meaning|Description|Schema|
+|---|---|---|---|
+|204|[No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5)|Job DELETE: NO_CONTENT|None|
+|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Job DELETE: BAD_REQUEST|None|
+|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|Job DELETE: NOT_FOUND|None|
+
+
+
+## Search Jobs by filter
+
+
+
+> Code samples
+
+`GET /hts/jobs/query`
+
+Returns jobs that fulfills the filter predicate. For examples, one could provide {status: } in the map to query all jobs with that status.
+
+
+
+
+
+
+
+
+```json
+{
+ "entity": {
+ "tableId": "my_table",
+ "databaseId": "my_database",
+ "tableVersion": "string",
+ "metadataLocation": "string"
+ }
+}
+
+```
+
+Request containing details of the User Table to be created/updated
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|entity|[UserTable](#schemausertable)|true|none|The entity object that clients want to create/update in the target house table.|
+
+
UserTable
+
+
+
+
+
+
+```json
+{
+ "tableId": "my_table",
+ "databaseId": "my_database",
+ "tableVersion": "string",
+ "metadataLocation": "string"
+}
+
+```
+
+The entity object that clients want to create/update in the target house table.
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|tableId|string|true|none|Unique Resource identifier for a table within a Database.|
+|databaseId|string|true|none|Unique Resource identifier for the Database containing the Table. Together with tableID they form a composite primary key for a user table.|
+|tableVersion|string|false|none|Current Version of the user table.|
+|metadataLocation|string|true|none|Full URI for the file manifesting the newest version of a user table.|
+
+
EntityResponseBodyUserTable
+
+
+
+
+
+
+```json
+{
+ "entity": {
+ "tableId": "my_table",
+ "databaseId": "my_database",
+ "tableVersion": "string",
+ "metadataLocation": "string"
+ }
+}
+
+```
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|entity|[UserTable](#schemausertable)|true|none|The entity object that clients want to create/update in the target house table.|
+
+
CreateUpdateEntityRequestBodyJob
+
+
+
+
+
+
+```json
+{
+ "entity": {
+ "jobId": "24efc962-9962-4522-b0b6-29490d7d8a0e",
+ "state": "QUEUED",
+ "version": "539482",
+ "jobName": "my_job",
+ "clusterId": "my_cluster",
+ "creationTimeMs": 1651002318265,
+ "startTimeMs": 1651002318265,
+ "finishTimeMs": 1651002318265,
+ "lastUpdateTimeMs": 1651002318265,
+ "jobConf": "{'jobType': 'RETENTION', 'table': 'db.tb'}",
+ "heartbeatTimeMs": 1651002318265,
+ "executionId": "application_1642969576960_13278206"
+ }
+}
+
+```
+
+Request containing details of the User Table to be created/updated
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|entity|[Job](#schemajob)|true|none|The entity object that clients want to create/update in the target house table.|
+
+
Job
+
+
+
+
+
+
+```json
+{
+ "jobId": "24efc962-9962-4522-b0b6-29490d7d8a0e",
+ "state": "QUEUED",
+ "version": "539482",
+ "jobName": "my_job",
+ "clusterId": "my_cluster",
+ "creationTimeMs": 1651002318265,
+ "startTimeMs": 1651002318265,
+ "finishTimeMs": 1651002318265,
+ "lastUpdateTimeMs": 1651002318265,
+ "jobConf": "{'jobType': 'RETENTION', 'table': 'db.tb'}",
+ "heartbeatTimeMs": 1651002318265,
+ "executionId": "application_1642969576960_13278206"
+}
+
+```
+
+The entity object that clients want to create/update in the target house table.
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|jobId|string|true|none|Unique Resource identifier for a job within a Database.|
+|state|string|false|none|State for the job|
+|version|string|false|none|Version of the job entry in HTS. HTS internally generates the next version after a successful PUT.The value would be a string representing a random integer.|
+|jobName|string|true|none|Name of a job, doesn't need to be unique|
+|clusterId|string|true|none|Unique identifier for the cluster|
+|creationTimeMs|integer(int64)|false|none|Job creation time in unix epoch milliseconds|
+|startTimeMs|integer(int64)|false|none|Job start time in unix epoch milliseconds|
+|finishTimeMs|integer(int64)|false|none|Job finish time in unix epoch milliseconds|
+|lastUpdateTimeMs|integer(int64)|false|none|Job contents last update time in unix epoch milliseconds|
+|jobConf|string|false|none|Job config|
+|heartbeatTimeMs|integer(int64)|false|none|Running job heartbeat timestamp in milliseconds|
+|executionId|string|false|none|Launched job execution id specific to engine|
+
+
+
+> Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
+
+API description for OpenHouse API
+
+Base URLs:
+
+* http://localhost:8080
+
+Terms of service
+
+License: Apache 2.0
+
+
+
+
+
+
+
+
+```json
+{
+ "jobName": "my_job",
+ "clusterId": "my_cluster",
+ "jobConf": "{'jobType': 'RETENTION', 'table': 'db.tb'}"
+}
+
+```
+
+Request containing details of the Job to be created
+
+### Properties
+
+|Name|Type|Required|Restrictions|Description|
+|---|---|---|---|---|
+|jobName|string|true|none|Name of a job, doesn't need to be unique|
+|clusterId|string|true|none|Unique identifier for the cluster|
+|jobConf|[JobConf](#schemajobconf)|false|none|Job config|
+
+