diff --git a/src/config/types.ts b/src/config/types.ts
index fc3a3afe5..ee919abde 100644
--- a/src/config/types.ts
+++ b/src/config/types.ts
@@ -14,11 +14,13 @@ export type Source = {
 		 * メンテナの連絡先(URLかmailto形式のURL)
 		 */
 		url: string;
+		email?: string;
 		repository_url?: string;
 		feedback_url?: string;
 	};
 	name?: string;
 	description?: string;
+	languages?: string[];
 	welcome_bg_url?: string;
 	url: string;
 	port: number;
diff --git a/src/server/api/mastodon.ts b/src/server/api/mastodon.ts
index f2ce1c384..a9253be80 100644
--- a/src/server/api/mastodon.ts
+++ b/src/server/api/mastodon.ts
@@ -1,10 +1,85 @@
 import * as Router from 'koa-router';
 import User from '../../models/user';
 import { toASCII } from 'punycode';
+import config from '../../config';
+import Meta from '../../models/meta';
+import { ObjectID } from 'bson';
+const pkg = require('../../../package.json');
 
 // Init router
 const router = new Router();
 
+router.get('/v1/custom_emojis', async ctx => ctx.body = {});
+
+router.get('/v1/instance', async ctx => { // TODO: This is a temporary implementation. Consider creating helper methods!
+	const meta = await Meta.findOne() || {};
+	const { originalNotesCount, originalUsersCount } = meta.stats || {
+		originalNotesCount: 0,
+		originalUsersCount: 0
+	};
+	const domains = await User.distinct('host', { host: { $ne: null } }) as any as [] || [];
+	const maintainer = await User.findOne({ isAdmin: true }) || {
+		_id: ObjectID.createFromTime(0),
+		username: '', // TODO: Consider making this better!
+		host: config.host,
+		name: '',
+		isLocked: false,
+		isBot: false,
+		createdAt: new Date(0),
+		description: '',
+		avatarUrl: '',
+		bannerUrl: '',
+		followersCount: 0,
+		followingCount: 0,
+		notesCount: 0
+	};
+	const acct = maintainer.host ? `${maintainer.username}@${maintainer.host}` : maintainer.username;
+
+	ctx.body = {
+		uri: config.hostname,
+		title: config.name || 'Misskey',
+		description: config.description || '',
+		email: config.maintainer.email || config.maintainer.url.startsWith('mailto:') ? config.maintainer.url.slice(7) : '',
+		version: `0.0.0:compatible:misskey:${pkg.version}`, // TODO: How to tell about that this is an api for compatibility?
+		thumbnail: meta.bannerUrl,
+		/*
+		urls: {
+			streaming_api: config.ws_url + '/mastodon' // TODO: Implement compatible streaming API
+		}, */
+		stats: {
+			user_count: originalUsersCount,
+			status_count: originalNotesCount,
+			domain_count: domains.length
+		},
+		languages: config.languages || [ 'ja' ],
+		contact_account: {
+			id: maintainer._id,
+			username: maintainer.username,
+			acct: acct,
+			display_name: maintainer.name || '',
+			locked: maintainer.isLocked,
+			bot: maintainer.isBot,
+			created_at: maintainer.createdAt,
+			note: maintainer.description,
+			url: `${config.url}/@${acct}`,
+			avatar: maintainer.avatarUrl || '',
+			/*
+			avatar_static: maintainer.avatarUrl || '', // TODO: Implement static avatar url (ensure non-animated GIF)
+			*/
+			header: maintainer.bannerUrl || '',
+			/*
+			header_static: maintainer.bannerUrl || '', // TODO: Implement static header url (ensure non-animated GIF)
+			*/
+			followers_count: maintainer.followersCount,
+			following_count: maintainer.followingCount,
+			statuses_count: maintainer.notesCount,
+			emojis: [],
+			moved: null,
+			fields: null
+		}
+	};
+});
+
 router.get('/v1/instance/peers', async ctx => {
 	const peers = await User.distinct('host', { host: { $ne: null } }) as any as string[];
 	const punyCodes = peers.map(peer => toASCII(peer));