diff --git a/.changeset/serious-islands-beg.md b/.changeset/serious-islands-beg.md
new file mode 100644
index 0000000..296bd2b
--- /dev/null
+++ b/.changeset/serious-islands-beg.md
@@ -0,0 +1,5 @@
+---
+"@gw2api/types": patch
+---
+
+Add types for `/v2/achievements`, `/v2/achievements/categories` and `/v2/achievements/groups`
diff --git a/packages/types/data/achievement-category.ts b/packages/types/data/achievement-category.ts
new file mode 100644
index 0000000..fee91a5
--- /dev/null
+++ b/packages/types/data/achievement-category.ts
@@ -0,0 +1,59 @@
+import type { SchemaAfter, SchemaVersion } from "../schema";
+
+/**
+ * AchievementCategory as returned from `/v2/achievements/categories`
+ * @see https://wiki.guildwars2.com/wiki/API:2/achievements/categories
+ */
+export type AchievementCategory<Schema extends SchemaVersion> =
+  Schema extends undefined ? AchievementCategory_Base :
+  Schema extends SchemaAfter<'2022-03-23T19:00:00.000Z'> | 'latest' ? AchievementCategory_2022_03_23 :
+  AchievementCategory_Base;
+
+
+interface AchievementCategory_Base {
+  /** The id of the achievement category */
+  id: number;
+
+  /** The name of the achievement category */
+  name: string;
+
+  /** The description of the achievement category */
+  description: string;
+
+  /** The icon of the achievement category */
+  icon: string;
+
+  /** The order of the achievement category in which they appear in-game (ascending) */
+  order: number;
+
+  /** List of achievement ids that are part of this achievement category */
+  achievements: number[];
+}
+
+interface AchievementCategory_2022_03_23 extends Omit<AchievementCategory_Base, 'achievements'> {
+  /** List of achievements that are currently part of this achievement category */
+  achievements: AchievementCategoryAchievement[];
+
+  /** List of achievements that will be part of this achievement category tomorrow, if this achievement category is on a rotation */
+  tomorrow?: AchievementCategoryAchievement[];
+}
+
+interface AchievementCategoryAchievement {
+  /** The id of the achievement */
+  id: number;
+
+  /** Flags of the achievement */
+  flags?: ('PvE' | 'PvP' | 'WvW' | 'SpecialEvent')[];
+
+  /** The required level range for this achievement to be available in-game (both inclusive)  */
+  level?: [number, number];
+
+  /** Required access to an extension for this achievement to be available in-game */
+  required_access?: {
+    /** The extension for this requirement */
+    product: 'PathOfFire' | 'HeartOfThorns';
+
+    /** Condition for this extension */
+    condition: 'NoAccess' | 'HasAccess';
+  };
+}
diff --git a/packages/types/data/achievement-group.ts b/packages/types/data/achievement-group.ts
new file mode 100644
index 0000000..4d6a97a
--- /dev/null
+++ b/packages/types/data/achievement-group.ts
@@ -0,0 +1,20 @@
+/**
+ * AchievementGroup as returned from `/v2/achievements/groups`
+ * @see https://wiki.guildwars2.com/wiki/API:2/achievements/groups
+ */
+export interface AchievementGroup {
+  /** The id of the achievement group */
+  id: string;
+
+  /** The name of the achievement group */
+  name: string;
+
+  /** The description of the achievement group */
+  description: string;
+
+  /** The order in-game (ascending) */
+  order: number;
+
+  /** Achievement category ids that are part of this group */
+  categories: number[];
+};
diff --git a/packages/types/data/achievement.ts b/packages/types/data/achievement.ts
new file mode 100644
index 0000000..b87db04
--- /dev/null
+++ b/packages/types/data/achievement.ts
@@ -0,0 +1,85 @@
+/**
+ * Achievement as returned from `/v2/achievements`
+ * @see https://wiki.guildwars2.com/wiki/API:2/achievements
+ */
+export interface Achievement {
+  /** The id of the achievement */
+  id: number;
+
+  /** The name of the achievement */
+  name: string;
+
+  /** Description of the achievement */
+  description: string;
+
+  /** The icon of the achievement if different from the achievement category */
+  icon?: string;
+
+  /** The type of the achievement */
+  type: 'Default' | 'ItemSet';
+
+  /** Achievement Flags */
+  flags: AchievementFlags[];
+
+  /** The description of the achievement when it is still locked */
+  locked_text: string;
+
+  /** List of achievement ids that have to be completed before unlocking this achievement */
+  prerequisites?: number[];
+
+  /** Achievement requirement */
+  requirement: string;
+
+  /** Achievement objectives */
+  bits?: AchievementBit[];
+
+  /** Final rewards */
+  rewards?: AchievementReward[];
+
+  /** Reward tiers */
+  tiers: AchievementTier[];
+
+  /** Maximum AP for repeatable achievements */
+  point_cap?: number;
+};
+
+export type AchievementFlags =
+  | 'Pvp'
+  | 'CategoryDisplay'
+  | 'MoveToTop'
+  | 'IgnoreNearlyComplete'
+  | 'Repeatable'
+  | 'Hidden'
+  | 'RequiresUnlock'
+  | 'RepairOnLogin'
+  | 'Daily'
+  | 'Weekly'
+  | 'Monthly'
+  | 'Permanent'
+
+export type AchievementBit =
+  | { type: 'Text', text: string }
+  | { type: 'Item' | 'Skin' | 'Minipet', id: number }
+
+export type AchievementReward =
+  | { type: 'Item', id: number, count: number }
+  | { type: 'Title', id: number }
+  | { type: 'Mastery', id: number, region: MasteryRegion }
+  | { type: 'Coins', count: number }
+
+export type MasteryRegion =
+  | 'Tyria'    // core
+  | 'Maguuma'  // HoT
+  | 'Desert'   // PoF
+  | 'Tundra'   // Icebrood
+  | 'Jade'     // EoD
+  | 'Sky'      // SotO
+  | 'Unknown'; // Non whitelisted regions for future expansions
+
+export type AchievementTier = {
+  /** Number of objectives that need to be completed */
+  count: number;
+
+  /** AP rewarded for this tier */
+  points: number;
+}
diff --git a/packages/types/endpoints.ts b/packages/types/endpoints.ts
index 44e612e..12b1ede 100644
--- a/packages/types/endpoints.ts
+++ b/packages/types/endpoints.ts
@@ -6,6 +6,9 @@ import type { AccountLegendaryarmory } from './data/account-legendaryarmory';
 import type { AccountMaterials } from './data/account-material';
 import type { AccountWallet } from './data/account-wallet';
 import type { AccountWizardsVaultListing, AccountWizardsVaultMetaObjectives, AccountWizardsVaultSpecialObjectives } from './data/account-wizardsvault';
+import type { Achievement } from './data/achievement';
+import type { AchievementCategory } from './data/achievement-category';
+import type { AchievementGroup } from './data/achievement-group';
 import type { Character, CharacterBackstory, CharacterBuildTab, CharacterCore, CharacterCrafting, CharacterEquipment, CharacterEquipmentTab, CharacterInventory, CharacterRecipes, CharacterSkills, CharacterSpecializations, CharacterTraining } from './data/character';
 import type { Color } from './data/color';
 import type { Listing, Price, TransactionCurrent, TransactionHistoric } from './data/commerce';
@@ -419,6 +422,9 @@ export type EndpointType<Url extends KnownEndpoint | (string & {}), Schema exten
   Url extends `/v2/characters/${string}/training` ? CharacterTraining :
   Url extends BulkExpandedEndpointUrl<'/v2/characters', string> ? BulkExpandedResponseType<'/v2/characters', Url, string, Character<Schema>> :
   Url extends CreateSubtokenUrl<'/v2/createsubtoken'> ? Createsubtoken :
+  Url extends BulkExpandedEndpointUrl<'/v2/achievements/categories', number> ? BulkExpandedResponseType<'/v2/achievements/categories', Url, number, AchievementCategory<Schema>> :
+  Url extends BulkExpandedEndpointUrl<'/v2/achievements/groups', number> ? BulkExpandedResponseType<'/v2/achievements/groups', Url, number, AchievementGroup> :
+  Url extends BulkExpandedEndpointUrl<'/v2/achievements', number> ? BulkExpandedResponseType<'/v2/achievements', Url, number, Achievement> :
   Url extends BulkExpandedEndpointUrl<'/v2/colors', number> ? BulkExpandedResponseType<'/v2/colors', Url, number, Color> :
   Url extends BulkExpandedEndpointUrl<'/v2/currencies', number> ? BulkExpandedResponseType<'/v2/currencies', Url, number, Currency> :
   Url extends BulkExpandedEndpointUrl<'/v2/guild/upgrades', number> ? BulkExpandedResponseType<'/v2/guild/upgrades', Url, number, GuildUpgrade> :