
Research
/Security News
737 Chrome VPN Extensions Linked to Brand Impersonation and Browser Traffic Redirection
The campaign amassed more than 75,000 installs by targeting Russian-speaking users seeking access to blocked services.
Official TypeScript/JavaScript SDK for ApogeoAPI — IP geolocation, countries, cities, and exchange rates
Official TypeScript SDK for Geo API - Professional geographic data API with comprehensive country, state, and city information.
npm install @geo-api/sdk
# or with yarn
yarn add @geo-api/sdk
# or with pnpm
pnpm add @geo-api/sdk
import { GeoAPI } from '@geo-api/sdk';
// Initialize with API key (recommended)
const client = new GeoAPI({
apiKey: 'geoapi_live_xxxxx',
baseURL: 'https://api.yourcompany.com/v1' // optional
});
// Get all countries
const countries = await client.geo.getCountries();
console.log(`Total countries: ${countries.length}`);
// Search for cities
const cities = await client.geo.searchCities('New York', 10);
console.log(cities);
// Get usage statistics
const dashboard = await client.account.getDashboard();
console.log(`API calls this month: ${dashboard.usage.requestsThisMonth}`);
const client = new GeoAPI({
apiKey: 'geoapi_live_xxxxx'
});
const client = new GeoAPI({
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
});
// Or set token after initialization
client.setToken('new_token_here');
// Register new user
const { user, access_token, refresh_token } = await client.auth.register({
email: 'user@example.com',
password: 'securePassword123',
username: 'johndoe'
});
// Login
const tokens = await client.auth.login({
email: 'user@example.com',
password: 'securePassword123'
});
// Token is automatically set after login
console.log('Logged in as:', tokens.user.username);
// Refresh token
const newTokens = await client.auth.refreshToken({
refresh_token: tokens.refresh_token
});
// Get all countries
const countries = await client.geo.getCountries();
// Get country by ISO code
const usa = await client.geo.getCountryByIso('US');
console.log(usa.name); // "United States"
console.log(usa.capital); // "Washington"
console.log(usa.currency); // "USD"
// Search countries
const matching = await client.geo.searchCountries('united', 5);
// Get all states of a country
const usStates = await client.geo.getStates('US');
console.log(`US has ${usStates.length} states`);
// Get specific state
const california = await client.geo.getStateById(1234);
console.log(california.name); // "California"
// Search states
const texasMatch = await client.geo.searchStates('texas', 1);
// Get cities of a state
const californiaCities = await client.geo.getCities(1234, 100, 0);
// Get specific city
const city = await client.geo.getCityById(5678);
console.log(`${city.name}, ${city.state.name}`);
// Search cities
const newYorkCities = await client.geo.searchCities('New York', 10);
// Search across all types
const results = await client.geo.search({
query: 'san',
limit: 20,
offset: 0,
type: 'city' // optional: 'country' | 'state' | 'city'
});
console.log(`Found ${results.total} results`);
// Get complete dashboard
const dashboard = await client.account.getDashboard();
console.log('User:', dashboard.user.username);
console.log('Tier:', dashboard.subscription.tier);
console.log('Usage:', dashboard.usage.requestsThisMonth, '/', dashboard.usage.monthlyQuota);
console.log('API Keys:', dashboard.apiKeys.active, '/', dashboard.apiKeys.max);
// Update profile
await client.account.updateProfile({
username: 'new_username',
email: 'newemail@example.com'
});
// Change password
await client.account.changePassword({
currentPassword: 'oldpass123',
newPassword: 'newpass456'
});
// Get usage for date range
const stats = await client.account.getUsage({
startDate: new Date('2024-01-01'),
endDate: new Date('2024-01-31'),
groupBy: 'day' // or 'month'
});
stats.forEach(stat => {
console.log(`${stat.date}: ${stat.requests} requests`);
});
// List all API keys
const keys = await client.apiKeys.list();
// Create new API key
const newKey = await client.apiKeys.create({
name: 'Production Server',
expiresAt: new Date('2025-12-31')
});
console.log('🔑 Save this key:', newKey.key);
// ⚠️ Key is only shown once!
// Rename key
await client.apiKeys.update(keyId, {
name: 'Production Server v2'
});
// Revoke key (deactivate)
await client.apiKeys.revoke(keyId);
// Reactivate key
await client.apiKeys.activate(keyId);
// Delete permanently
await client.apiKeys.delete(keyId);
// Create checkout session
const checkout = await client.billing.createCheckoutSession(
'professional', // tier
'https://myapp.com/success', // success URL
'https://myapp.com/cancel' // cancel URL
);
// Redirect user to Stripe
window.location.href = checkout.url;
// Access billing portal
const portal = await client.billing.createPortalSession(
'https://myapp.com/account' // return URL
);
// Redirect user to Stripe portal
window.location.href = portal.url;
// Get all invoices
const invoices = await client.billing.getInvoices(10);
invoices.forEach(invoice => {
console.log(`${invoice.created}: $${invoice.amount/100} - ${invoice.status}`);
console.log(`PDF: ${invoice.invoice_pdf}`);
});
// Get specific invoice
const invoice = await client.billing.getInvoice('in_xxxxx');
// Cancel at period end
await client.billing.cancelSubscription();
// User keeps access until period ends
// Reactivate before period ends
await client.billing.reactivateSubscription();
// Create webhook
const webhook = await client.webhooks.create({
url: 'https://myapp.com/webhooks/geo-api',
events: [
'usage.quota_warning',
'usage.quota_exceeded',
'subscription.updated'
]
});
console.log('Webhook ID:', webhook.id);
console.log('Secret:', webhook.secret); // Use to validate payloads
// List all webhooks
const webhooks = await client.webhooks.list();
// Update webhook
await client.webhooks.update(webhookId, {
url: 'https://myapp.com/new-webhook-url',
events: ['subscription.created', 'subscription.canceled']
});
// Test webhook
const result = await client.webhooks.test(webhookId);
console.log('Test success:', result.success);
// Deactivate
await client.webhooks.deactivate(webhookId);
// Delete
await client.webhooks.delete(webhookId);
// Get webhook delivery logs
const logs = await client.webhooks.getLogs(webhookId, 50);
logs.forEach(log => {
console.log(`${log.createdAt}: ${log.event} - ${log.success ? '✅' : '❌'}`);
if (!log.success) {
console.log(` Status: ${log.statusCode}`);
}
});
import { GeoAPI, GeoAPIError } from '@geo-api/sdk';
const client = new GeoAPI({ apiKey: 'xxx' });
try {
const country = await client.geo.getCountryByIso('INVALID');
} catch (error) {
if (error instanceof GeoAPIError) {
console.error('Status:', error.statusCode);
console.error('Message:', error.message);
console.error('Response:', error.response);
// Handle specific errors
if (error.statusCode === 404) {
console.log('Country not found');
} else if (error.statusCode === 429) {
console.log('Rate limit exceeded, retry after:', error.response?.retryAfter);
} else if (error.statusCode === 403) {
console.log('Quota exceeded or invalid API key');
}
} else {
console.error('Unexpected error:', error);
}
}
const client = new GeoAPI({
apiKey: 'geoapi_live_xxxxx',
baseURL: 'https://api.yourcompany.com/v1',
timeout: 30000, // 30 seconds
retries: 3, // retry failed requests 3 times
debug: true // enable debug logging
});
const client = new GeoAPI({
apiKey: 'xxx',
debug: true
});
// Logs all requests and retries
// [SDK] GET /geo/countries
// [SDK] Response 200 from /geo/countries
// Development
const devClient = new GeoAPI({
apiKey: process.env.DEV_API_KEY,
baseURL: 'http://localhost:3000/v1'
});
// Production
const prodClient = new GeoAPI({
apiKey: process.env.PROD_API_KEY,
baseURL: 'https://api.yourcompany.com/v1'
});
import { GeoAPI } from '@geo-api/sdk';
const client = new GeoAPI({
apiKey: process.env.GEO_API_KEY!
});
async function main() {
// 1. Get dashboard
const dashboard = await client.account.getDashboard();
console.log(`Welcome ${dashboard.user.username}!`);
console.log(`You're on the ${dashboard.subscription.tier} plan`);
console.log(`Usage: ${dashboard.usage.usagePercentage}%`);
// 2. Query geography data
const countries = await client.geo.getCountries();
console.log(`\nTotal countries: ${countries.length}`);
// 3. Search for specific location
const cities = await client.geo.searchCities('Paris', 5);
console.log(`\nCities named Paris:`);
cities.forEach(city => {
console.log(`- ${city.name}, ${city.state?.name}, ${city.country?.name}`);
});
// 4. Check usage
const usage = await client.account.getUsage({
startDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
endDate: new Date(),
groupBy: 'day'
});
console.log(`\nLast 30 days usage:`, usage.length, 'days');
}
main().catch(console.error);
Full TypeScript support with complete type definitions:
import { GeoAPI, Country, City, Tier, WebhookEvent } from '@geo-api/sdk';
const client = new GeoAPI({ apiKey: 'xxx' });
// All responses are fully typed
const country: Country = await client.geo.getCountryByIso('US');
const cities: City[] = await client.geo.searchCities('London', 10);
// Enums are typed
const tier: Tier = 'professional';
const events: WebhookEvent[] = ['usage.quota_warning', 'subscription.updated'];
Contributions are welcome! Please open an issue or submit a pull request.
MIT © Geo API Team
Made with ❤️ by the Geo API Team
FAQs
Official TypeScript/JavaScript SDK for ApogeoAPI — IP geolocation, countries, cities, and exchange rates
The npm package apogeoapi receives a total of 6 weekly downloads. As such, apogeoapi popularity was classified as not popular.
We found that apogeoapi demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
The campaign amassed more than 75,000 installs by targeting Russian-speaking users seeking access to blocked services.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.