@crosspost/sdk
SDK for interacting with the Crosspost API.
Installation
bun install @crosspost/sdk
Quick Start
import { CrosspostClient, CrosspostError, isAuthError } from '@crosspost/sdk';
const client = new CrosspostClient({
baseUrl: 'https://your-crosspost-api.com',
});
client.setAuthentication({
accountId: 'your-account.near',
publicKey: 'ed25519:...',
signature: '...',
message: '...',
});
if (client.isAuthenticated()) {
console.log('Client has authentication data');
}
async function authorizeNearAccount() {
try {
const authResponse = await client.auth.authorizeNearAccount();
console.log('NEAR authorization successful');
console.log('Account ID:', authResponse.accountId);
console.log('Status:', authResponse.status);
console.log('Connected platforms:', authResponse.connectedPlatforms);
return true;
} catch (error) {
console.error('NEAR authorization failed');
if (error instanceof CrosspostError) {
console.error('Error code:', error.code);
console.error('Status:', error.status);
console.error('Details:', error.details);
console.error('Recoverable:', error.recoverable);
}
return false;
}
}
async function unauthorizeNearAccount() {
try {
const response = await client.auth.unauthorizeNearAccount();
console.log('NEAR account unauthorized');
console.log('Status:', response.status);
console.log('Message:', response.message);
return true;
} catch (error) {
console.error('Failed to unauthorize NEAR account');
if (error instanceof CrosspostError) {
console.error('Error code:', error.code);
console.error('Status:', error.status);
console.error('Details:', error.details);
}
return false;
}
}
async function revokePlatformAuth(platform) {
try {
const response = await client.auth.revokeAuth(platform);
console.log(`${platform} authorization revoked`);
console.log('Status:', response.status);
console.log('Platform:', response.platform);
console.log('Message:', response.message);
return true;
} catch (error) {
console.error(`Failed to revoke ${platform} authorization`);
if (error instanceof CrosspostError) {
console.error('Error code:', error.code);
console.error('Status:', error.status);
console.error('Details:', error.details);
}
return false;
}
}
async function createPost() {
try {
const response = await client.post.createPost({
targets: [{ platform: 'twitter', userId: 'your-twitter-id' }],
content: {
text: 'Hello from Crosspost SDK!',
},
});
console.log('Post created successfully');
console.log('Post ID:', response.id);
console.log('Platform:', response.platform);
console.log('URL:', response.url);
console.log('Created at:', response.createdAt);
} catch (error) {
if (isAuthError(error)) {
console.error('Authentication required. Attempting to authorize...');
const authorized = await authorizeNearAccount();
if (authorized) {
return createPost();
}
} else {
console.error('Error creating post:', error);
if (error instanceof CrosspostError) {
if (isPlatformError(error)) {
console.error('Platform:', error.platform);
console.error('Error code:', error.code);
console.error('Details:', error.details);
} else if (isRateLimitError(error)) {
console.error('Rate limited until:', error.details?.rateLimit?.reset);
} else if (isValidationError(error)) {
console.error('Validation errors:', error.details?.validationErrors);
}
if (error.recoverable) {
console.log('This error is recoverable - retry may succeed');
}
} else if (error instanceof Error) {
console.error('Unexpected error:', error.message);
}
}
}
}
API Reference
CrosspostClient
constructor(config?: {
baseUrl?: string;
nearAuthData?: NearAuthData;
timeout?: number;
retries?: number;
})
Methods
setAuthentication(nearAuthData: NearAuthData): Promise<void>
- Sets authentication data
isAuthenticated(): boolean
- Checks if client is authenticated
Auth API (client.auth)
authorizeNearAccount(): Promise<NearAuthorizationResponse>
- Authorizes NEAR account
unauthorizeNearAccount(): Promise<NearAuthorizationResponse>
- Unauthorizes NEAR account
getNearAuthorizationStatus(): Promise<NearAuthorizationResponse>
- Checks authorization status
loginToPlatform(platform, options?): Promise<EnhancedApiResponse<any>>
- Initiates OAuth flow
refreshToken(platform): Promise<EnhancedApiResponse<any>>
- Refreshes platform token
refreshProfile(platform): Promise<EnhancedApiResponse<any>>
- Refreshes user profile
getAuthStatus(platform): Promise<AuthStatusResponse>
- Gets authentication status
revokeAuth(platform): Promise<AuthRevokeResponse>
- Revokes platform access
getConnectedAccounts(): Promise<ConnectedAccountsResponse>
- Lists connected accounts
Post API (client.post)
Each post operation accepts a request object that includes:
targets
: Array of { platform: string, userId: string }
specifying where to perform the action
- Additional parameters specific to each operation
Available methods:
createPost(request: CreatePostRequest): Promise<CreatePostResponse>
- Creates posts on specified
platforms
repost(request: RepostRequest): Promise<RepostResponse>
- Reposts an existing post
quotePost(request: QuotePostRequest): Promise<QuotePostResponse>
- Quotes an existing post
replyToPost(request: ReplyToPostRequest): Promise<ReplyToPostResponse>
- Replies to a post
likePost(request: LikePostRequest): Promise<LikePostResponse>
- Likes a post
unlikePost(request: UnlikePostRequest): Promise<UnlikePostResponse>
- Unlikes a post
deletePost(request: DeletePostRequest): Promise<DeletePostResponse>
- Deletes posts
Activity API (client.activity)
getLeaderboard(options): Promise<LeaderboardResponse>
- Gets activity leaderboard
getAccountActivity(signerId, options): Promise<AccountActivityResponse>
- Gets account activity
getAccountPosts(signerId, options): Promise<AccountPostsResponse>
- Gets account posts
System API (client.system)
getRateLimits(): Promise<RateLimitsResponse>
- Gets all rate limits
getEndpointRateLimit(endpoint): Promise<EndpointRateLimitResponse>
- Gets endpoint rate limit
getHealthStatus(): Promise<HealthStatusResponse>
- Gets API health status
Error Handling Utilities
import {
apiWrapper,
enrichErrorWithContext,
getErrorDetails,
getErrorMessage,
isAuthError,
isContentError,
isMediaError,
isNetworkError,
isPlatformError,
isPostError,
isRateLimitError,
isRecoverableError,
isValidationError,
} from '@crosspost/sdk';
if (isAuthError(error)) {
}
const message = getErrorMessage(error, 'Default message');
const details = getErrorDetails(error);
const enrichedError = enrichErrorWithContext(error, {
operation: 'createPost',
timestamp: Date.now(),
});
const result = await apiWrapper(
async () => {
return await fetch('/api/endpoint');
},
{ operation: 'fetchData' },
);
Usage Examples
Creating a Post
const textPostResponse = await client.post.createPost({
targets: [{
platform: 'twitter',
userId: 'your-twitter-id',
}],
content: [{
text: 'Hello from Crosspost SDK!',
}],
});
const mediaPostResponse = await client.post.createPost({
targets: [
{ platform: 'twitter', userId: 'your-twitter-id' },
{ platform: 'facebook', userId: 'your-facebook-id' },
],
content: [{
text: 'Check out this image!',
media: [{
data: imageBlob,
mimeType: 'image/jpeg',
altText: 'A beautiful sunset',
}],
}],
});
Post Interactions
await client.post.likePost({
targets: [{
platform: 'twitter',
userId: 'your-twitter-id',
}],
platform: 'twitter',
postId: '1234567890',
});
await client.post.repost({
targets: [
{ platform: 'twitter', userId: 'your-twitter-id' },
{ platform: 'facebook', userId: 'your-facebook-id' },
],
platform: 'twitter',
postId: '1234567890',
});
await client.post.replyToPost({
targets: [{
platform: 'twitter',
userId: 'your-twitter-id',
}],
platform: 'twitter',
postId: '1234567890',
content: [{
text: 'This is a reply!',
}],
});
await client.post.deletePost({
targets: [{
platform: 'twitter',
userId: 'your-twitter-id',
}],
posts: [{
platform: 'twitter',
userId: 'your-twitter-id',
postId: '1234567890',
}],
});
Getting Activity Data
const leaderboard = await client.activity.getLeaderboard({
timeframe: 'week',
limit: 10,
});
const activity = await client.activity.getAccountActivity('user.near', {
timeframe: 'month',
});
const posts = await client.activity.getAccountPosts('user.near', {
limit: 20,
offset: 0,
});
Checking Rate Limits
const rateLimits = await client.system.getRateLimits();
const postRateLimit = await client.system.getEndpointRateLimit('post');
Authentication and Security
Authentication Strategy
The SDK uses direct authentication with per-request signatures:
const client = new CrosspostClient({
baseUrl: 'https://your-crosspost-api.com',
});
client.setAuthentication({
accountId: 'your-account.near',
publicKey: 'ed25519:...',
signature: '...',
message: '...',
});