@feather-it/partner-sdk
v1.0.0
Published
LETO Domain Reseller API JavaScript/TypeScript SDK
Maintainers
Readme
LETO Partner SDK for JavaScript/TypeScript
Official JavaScript/TypeScript SDK for the LETO Domain Reseller API. To use the LETO Partner SDK, you must join the LETO Partner Program. You can join the LETO Partner Program at LETO Partner. (Currently unavailable; please contact [email protected] for inquiries.)
Installation
npm install @feather-it/partner-sdkor with yarn:
yarn add @feather-it/partner-sdkQuick Start
import { LetoClient } from '@feather-it/partner-sdk';
// Initialize the client
const client = new LetoClient({
tenantId: 'your-tenant-id',
serviceToken: 'your-service-token',
});
// Check domain availability
const availability = await client.domains.check('example.kr');
console.log(availability.available); // true or false
// Create a contact
const contact = await client.contacts.create({
name: {
national: '홍길동',
international: 'Hong Gil Dong',
},
email: '[email protected]',
phone: '+82-2-1234-5678',
mobile: '+82-10-1234-5678',
address: {
postalCode: '06234',
national: {
state: '서울특별시',
city: '강남구',
street: '테헤란로 128',
detail: '3층',
},
international: {
state: 'Seoul',
city: 'Gangnam-gu',
street: '128 Teheran-ro',
detail: '3F',
},
},
country: 'KR',
additionalContactData: {
ctfyCode: '020', // Required for KR domains
},
});
// Register a domain
const domain = await client.domains.register({
domain: 'example.kr',
period: 1,
nameservers: ['ns1.example.com', 'ns2.example.com'],
contact: {
registrant: contact.uuid!,
administrative: contact.uuid!,
},
});
console.log(`Domain registered: ${domain.domainName}`);Configuration
LetoConfig
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| tenantId | string | Yes | - | Your LETO tenant ID |
| serviceToken | string | Yes | - | Your service token from partner portal |
| baseUrl | string | No | https://api.leto.kr | API base URL |
| timeout | number | No | 30000 | Request timeout in milliseconds |
| retries | number | No | 3 | Number of retry attempts |
API Reference
Domains
Check Domain Availability
const result = await client.domains.check('example.kr');
// Returns: { domain: string, available: boolean, price?: number, currency?: string }Register Domain
const domain = await client.domains.register({
domain: 'example.kr',
period: 1, // years
nameservers: ['ns1.example.com', 'ns2.example.com'],
contact: {
registrant: 'contact-uuid',
administrative: 'contact-uuid',
technical: 'contact-uuid', // optional
billing: 'contact-uuid', // optional
},
});List Domains
const response = await client.domains.list({
page: 1,
size: 20,
status: 'active',
search: 'example',
});
// Returns paginated list with response.data, response.paginationGet Domain Details
const domain = await client.domains.get('example.kr');Delete Domain
await client.domains.delete('example.kr');
// Note: Only supported for limited TLDsGet WHOIS Information
const whois = await client.domains.whois('example.kr');Domain Lock Management
Get All Lock Statuses
const locks = await client.domains.getLocks('example.kr');
// Returns: { transferLock: boolean, transferAutoReject: boolean, updateLock: boolean }Transfer Lock
// Get transfer lock status
const status = await client.domains.getTransferLock('example.kr');
// Set transfer lock
await client.domains.setTransferLock('example.kr', true); // lock
await client.domains.setTransferLock('example.kr', false); // unlockTransfer Auto-Reject
// Get auto-reject status
const status = await client.domains.getTransferAutoReject('example.kr');
// Set auto-reject
await client.domains.setTransferAutoReject('example.kr', true);Update Lock
// Get update lock status
const status = await client.domains.getUpdateLock('example.kr');
// Set update lock
await client.domains.setUpdateLock('example.kr', true);Authorization Code
// Get auth code
const authCode = await client.domains.getAuthCode('example.kr');
console.log(authCode.code);
console.log(authCode.base64);
// Change auth code
const newAuthCode = await client.domains.changeAuthCode('example.kr');Nameservers
// Get nameservers
const nameservers = await client.domains.getNameservers('example.kr');
// Update nameservers (2-5 nameservers required)
await client.domains.updateNameservers('example.kr', [
'ns1.example.com',
'ns2.example.com',
]);Domain Contacts
// Get domain contacts
const contacts = await client.domains.getContact('example.kr');
// Update domain contacts
await client.domains.updateContact('example.kr', {
registrant: 'new-contact-uuid',
administrative: 'new-contact-uuid',
});Domain Renewal
// Renew domain (limited to once per day)
const renewal = await client.domains.renew('example.kr', { period: 1 });
// Get renewal history
const renewals = await client.domains.getRenewalHistory('example.kr');
// Cancel renewal (limited TLDs only)
await client.domains.cancelRenewal('example.kr', 'renewal-uuid');DNSSEC
// Get DNSSEC settings
const dnssec = await client.domains.getDNSSEC('example.kr');
// Configure DNSSEC
await client.domains.configureDNSSEC('example.kr', {
dsData: [
{
algorithm: 8,
digest: 'digest-hash',
digestType: 2,
keyTag: 12345,
},
],
});Contacts
Create Contact
const contact = await client.contacts.create({
name: {
national: '홍길동',
international: 'Hong Gil Dong',
},
email: '[email protected]',
phone: '+82-2-1234-5678',
mobile: '+82-10-1234-5678',
fax: '+82-2-1234-5679', // optional
address: {
postalCode: '06234',
national: {
state: '서울특별시',
city: '강남구',
street: '테헤란로 128',
detail: '3층',
},
international: {
state: 'Seoul',
city: 'Gangnam-gu',
street: '128 Teheran-ro',
detail: '3F',
},
},
country: 'KR',
additionalContactData: {
ctfyCode: '020', // Required for KR domains (KISA certification code)
},
description: 'Contact description', // optional
});List Contacts
const response = await client.contacts.list({
page: 1,
size: 20,
});
// Returns paginated listTransfers
Verify Authorization Code
const result = await client.transfers.verifyAuthCode({
domain: 'example.com',
authCode: 'auth-code-here',
});
console.log(result.valid); // true or falseInitiate Transfer
const transfer = await client.transfers.initiate({
domain: 'example.com',
authCode: 'auth-code-here',
period: 1, // optional, years to add
nameservers: ['ns1.example.com', 'ns2.example.com'], // optional
contact: {
// optional
registrant: 'contact-uuid',
administrative: 'contact-uuid',
},
});Get Transfer Status
const transfer = await client.transfers.get('transfer-uuid');
console.log(transfer.status); // pending, in_progress, completed, failed, rejected
console.log(transfer.direction); // in or outTLDs
List All TLDs
const tlds = await client.tlds.list();
// Returns array of all TLDs with pricing and rulesGet Specific TLD
const tld = await client.tlds.get('kr');
console.log(tld.prices.registration);
console.log(tld.prices.renewal);
console.log(tld.prices.transfer);
console.log(tld.rules);Transactions
const response = await client.transactions.list({
page: 1,
size: 20,
type: 'registration', // registration, renewal, transfer, deletion
status: 'completed', // pending, processing, completed, failed, refunded
startDate: '2025-01-01',
endDate: '2025-12-31',
});Account
const status = await client.account.getStatus();
console.log(status.tenantId);
console.log(status.status); // ACTIVE or SUSPENDED
console.log(status.balance.amount);
console.log(status.balance.currency);Error Handling
The SDK throws LetoApiError for API errors:
import { LetoClient, LetoApiError } from '@feather-it/partner-sdk';
try {
await client.domains.register({
domain: 'example.kr',
// ... other fields
});
} catch (error) {
if (error instanceof LetoApiError) {
console.error('API Error:', error.message);
console.error('Error Code:', error.code);
console.error('Timestamp:', error.timestamp);
console.error('Status Code:', error.statusCode);
console.error('Data:', error.data);
} else {
console.error('Network or other error:', error);
}
}TypeScript Support
This SDK is written in TypeScript and provides full type definitions:
import {
LetoClient,
Domain,
Contact,
Transfer,
TLD,
Transaction,
DomainStatus,
TransferStatus,
} from '@feather-it/partner-sdk';
// All types are fully typed
const domain: Domain = await client.domains.get('example.kr');
const contact: Contact = await client.contacts.create({ /* ... */ });Requirements
- Node.js >= 16.0.0
- TypeScript >= 5.0.0 (for TypeScript projects)
License
MIT
Support
For API support, please contact your Account Manager or reach out via the dedicated Slack channel.
Important Notes
- Domain renewal is limited to once per day per domain
- DNSSEC is currently only available for KR domains and may not work in some cases
- Domain deletion is only supported for limited TLDs
- Some operations require specific TLD support (check TLD rules first)
- KR domains require KISA certification code (
ctfyCode) in contact'sadditionalContactData
Development
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Lint
npm run lint
# Format
npm run format