TypeScript SDK
The TypeScript SDK (@shaped.ai/client) is *generated from the Shaped API
schema. It includes types and inline documentation so your editor’s
IntelliSense/auto‑completion can surface all methods, options, and return types
as you build.
Install
Install from npm:
npm install @shaped.ai/client
or with Yarn:
yarn add @shaped.ai/client
Instantiate the client
Import and construct the Client with your API key:
import { Client } from '@shaped.ai/client';
const client = new Client('YOUR_API_KEY');
You can also read the key from environment variables (Node.js):
import { Client } from '@shaped.ai/client';
const apiKey = process.env.SHAPED_API_KEY!;
const client = new Client(apiKey);
Load data from raw records
This pattern mirrors the Python examples and is useful when you want to push data directly from your application.
1. Create a custom table
Use the TableRequest type to define a CUSTOM schema and create it via
client.createTable:
import type { TableRequest } from '@shaped.ai/client';
const tableConfig: TableRequest = {
schema_type: 'CUSTOM',
name: 'pixar_movies',
column_schema: {
item_id: 'Int64',
movie_title: 'String',
poster_url: 'String',
description: 'String',
release_date: 'String',
cast: 'Array(String)',
},
};
await client.createTable(tableConfig);
2. Insert raw records
Insert arrays of JavaScript objects using insertTableRows:
const records: Array<Record<string, any>> = [
{
item_id: 187541,
movie_title: 'Incredibles 2 (2018)',
poster_url:
'https://m.media-amazon.com/images/M/MV5BMTEzNzY0OTg0NTdeQTJeQWpwZ15BbWU4MDU3OTg3MjUz._V1_QL75_UX380_CR0,0,380,562_.jpg',
description:
"The Incredibles family takes on a new mission which involves a change in family roles.",
release_date: '2018-06-15',
cast: ['Craig T. Nelson', 'Holly Hunter'],
},
{
item_id: 177765,
movie_title: 'Coco (2017)',
poster_url:
'https://m.media-amazon.com/images/M/MV5BMDIyM2E2NTAtMzlhNy00ZGUxLWI1NjgtZDY5MzhiMDc5NGU3XkEyXkFqcGc@._V1_QL75_UY562_CR7,0,380,562_.jpg',
description:
'Aspiring musician Miguel enters the Land of the Dead to find his great‑great‑grandfather.',
release_date: '2017-11-22',
cast: ['Anthony Gonzalez', 'Gael García Bernal'],
},
];
await client.insertTableRows('pixar_movies', records);
Load data from connectors (MongoDB example)
As with Python, connector tables are defined via the Tables API or CLI, and appear as normal tables when queried via the SDK.
1. Define a MongoDB connector table
Use the createTable method to sync an external data source to a Shaped table. This example uses a MongoDB table.
import type { TableRequest } from '@shaped.ai/client';
const tableConfig: TableRequest = {
"name": "mongodb_dataset",
"schema_type": "MONGODB",
"collection": "movies",
"database": "movielens",
"mongodb_connection_string": "mongodb://user:password@host:port/database",
"start_date": "2024-01-01",
}
await client.createTable(tableConfig);
The table mongodb_dataset will be synced on the schedule you configure and
is now available to engines and queries.
See the Connector Reference for a full list of external data sources you can sync with.
2. Use the connector table from TypeScript
You reference the connector table just like any other table when configuring engines in TypeScript:
import { Engine } from '@shaped.ai/client';
const mongoEngine = new Engine('mongodb_semantic_search');
mongoEngine.items('mongodb_dataset');
mongoEngine.withEmbedding({
name: 'mongo_text_embedding',
encoder: {
type: 'hugging_face',
model_name: 'sentence-transformers/all-MiniLM-L6-v2',
item_fields: ['document'], // JSON document column
},
});
await client.createEngine(mongoEngine);
For more on MongoDB options and behavior, see the MongoDB connector docs.
Create engines with vector embeddings
On TypeScript, you configure engines using the Engine helper class.
It wraps the engine configuration in a convenient, chainable interface.
1. Define the engine
import { Engine } from '@shaped.ai/client';
const semanticSearchEngine = new Engine('semantic_search');
2. Connect to an item table
Use .items to connect the engine to your table:
semanticSearchEngine.items('pixar_movies');
3. Configure an embedding index
Configure a HuggingFace encoder for semantic / vector search:
const embeddingModel = 'sentence-transformers/all-MiniLM-L6-v2';
semanticSearchEngine.withEmbedding({
name: 'movie_text_embedding',
encoder: {
type: 'hugging_face',
model_name: embeddingModel,
item_fields: ['movie_title', 'description'],
},
});
4. Create the engine (start encoding)
await client.createEngine(semanticSearchEngine);
Once status is ACTIVE, the engine is ready for queries.
Query data with the fluent builder
The TypeScript SDK exposes a builder pattern via RankQueryBuilder that
compiles to ShapedQL under the hood.
1. Basic lexical search
import { RankQueryBuilder } from '@shaped.ai/client';
const query = new RankQueryBuilder()
.from('item')
.retrieve(step =>
step.textSearch(
'$query',
{ type: 'lexical' },
{ limit: 50 },
),
)
.limit(20)
.build();
const results = await client.executeQuery(
'text_search',
query,
{ query: 'Incredibles' },
true,
);
2. Vector / semantic search
import { RankQueryBuilder } from '@shaped.ai/client';
const query = new RankQueryBuilder()
.from('item')
.retrieve(step =>
step.textSearch(
'$query',
{ type: 'vector', textEmbeddingRef: 'movie_text_embedding' },
{ limit: 50 },
),
)
.limit(20)
.build();
const results = await client.executeQuery(
'semantic_search',
query,
{ query: 'animated superhero family' },
true,
);
3. Hybrid search with multiple retrievers
import { RankQueryBuilder } from '@shaped.ai/client';
const query = new RankQueryBuilder()
.from('item')
.retrieve(step =>
step.textSearch(
'$query',
{ type: 'lexical' },
{ limit: 50, name: 'lexical_search' },
),
)
.retrieve(step =>
step.textSearch(
'$query',
{ type: 'vector', textEmbeddingRef: 'movie_text_embedding' },
{ limit: 50, name: 'vector_search' },
),
)
.limit(20)
.build();
const results = await client.executeQuery(
'hybrid_search',
query,
{ query: 'Pixar movies about family' },
true,
);
4. Personalized search with a value model
import { RankQueryBuilder } from '@shaped.ai/client';
const query = new RankQueryBuilder()
.from('item')
.retrieve(step =>
step.textSearch(
'$query',
{ type: 'lexical' },
{ limit: 50, name: 'lexical_search' },
),
)
.retrieve(step =>
step.textSearch(
'$query',
{ type: 'vector', textEmbeddingRef: 'movie_text_embedding' },
{ limit: 50, name: 'vector_search' },
),
)
.score({
valueModel: 'click_through_rate',
inputUserId: '$user_id',
inputInteractionsItemIds: '$interaction_item_ids',
})
.limit(20)
.build();
const results = await client.executeQuery(
'personalized_search',
query,
{
query: 'Pixar',
user_id: 'user1',
interaction_item_ids: ['187541', '177765', '1'],
},
true,
);
Next steps
- Use case guides: See Text search, Semantic search, Hybrid search, and Personalized search.
- Connectors: Explore the MongoDB connector and other integrations in the Connectors overview.